ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-07-07 03:59:51
Exec Total Coverage
Lines: 4013 5064 79.2%
Functions: 274 322 85.1%
Branches: 3114 5169 60.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 404 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 404 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 568 void maps_init_game_vars()
67 {
68 568 viewport = {};
69 568 viewport_mode = ViewportMode::CenterAndBound;
70 568 viewport_sprite_uid = 1;
71 568 currscr_for_passive_subscr = -1;
72 568 }
73
74 static region_ids_t current_region_ids;
75
76 14604306 static bool is_a_region(int map, int scr)
77 {
78 14604306 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 136565347 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 136563774 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 136563774 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 136551561 times.
136565347 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69602902 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69602901 times.
69602902 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28876079 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28861069 times.
✓ Branch 1 taken 15010 times.
✓ Branch 2 taken 461910 times.
✓ Branch 3 taken 28399159 times.
28876079 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9013096737 bool is_in_scrolling_region()
115 {
116 9013096737 return cur_region.screen_count > 1;
117 }
118
119 76764541 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76514407 times.
✓ Branch 1 taken 250134 times.
76764541 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15646322 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15244887 times.
15646322 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15243787 times.
✓ Branch 1 taken 1100 times.
15244887 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15646322 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64176 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64176 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63902 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64176 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63902 region.region_id = 0;
145 63902 region.origin_screen = screen;
146 63902 region.origin_screen_x = screen % 16;
147 63902 region.origin_screen_y = screen / 16;
148 63902 region.screen_width = 1;
149 63902 region.screen_height = 1;
150 63902 region.screen_count = 1;
151 63902 region.width = 256;
152 63902 region.height = 176;
153 63902 region_scr_dx = 0;
154 63902 region_scr_dy = 0;
155 63902 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64176 }
206
207 35830 void load_region(int dmap, int screen)
208 {
209 35830 clear_temporary_screens();
210
211 35830 int map = DMaps[dmap].map;
212 35830 current_region_ids = Regions[map].get_all_region_ids();
213
214 35830 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35830 cur_screen = cur_region.origin_screen;
216 35830 world_w = cur_region.width;
217 35830 world_h = cur_region.height;
218 35830 region_scr_count = cur_region.screen_count;
219 35830 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35830 region_num_rpos = cur_region.screen_count*176;
221 35830 scrolling_maze_last_solved_screen = 0;
222
223 35830 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36064 times.
✓ Branch 1 taken 35830 times.
71894 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 36064 times.
73138 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37074 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37074 times.
37074 if (screen < 136)
230 {
231 37074 screen_in_current_region[screen] = true;
232 37074 }
233 37074 }
234 36064 }
235
236 35830 mark_current_region_handles_dirty();
237 35830 }
238
239 35830 static void prepare_current_region_handles()
240 {
241 35830 current_region_rpos_handles_dirty = false;
242 35830 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36178 times.
✓ Branch 1 taken 35830 times.
72008 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 36178 times.
73252 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37074 int screen = cur_screen + x + y*16;
248 37074 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 259518 times.
296592 for (int layer = 0; layer <= 6; layer++)
250 {
251 259518 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84481 times.
✓ Branch 1 taken 175037 times.
259518 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175037 times.
✗ Branch 1 not taken.
175037 if (layer == 0) break;
255 175037 continue;
256 }
257
258 84481 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84481 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84481 current_region_screen_count += 1;
261 84481 }
262
263 37074 int num_handles_for_scr = current_region_screen_count - index_start;
264 37074 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37074 }
266 36178 }
267 35830 }
268
269 1779316842 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1779316842 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11029928 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11029928 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11029928 times.
11029928 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11029928 times.
11029928 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11029928 return current_region_rpos_handles_scr[scr->screen];
289 11029928 }
290
291 35830 void mark_current_region_handles_dirty()
292 {
293 35830 current_region_rpos_handles_dirty = true;
294 35830 }
295
296 36960 void clear_temporary_screens()
297 {
298
2/2
✓ Branch 0 taken 35185920 times.
✓ Branch 1 taken 36960 times.
35222880 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 35131334 times.
✓ Branch 1 taken 54586 times.
35185920 if (temporary_screens[i])
301 {
302 54586 free(temporary_screens[i]);
303 54586 temporary_screens[i] = NULL;
304 54586 }
305 35185920 }
306
307 36960 origin_scr = nullptr;
308 36960 hero_scr = nullptr;
309 36960 }
310
311 27941 std::vector<mapscr*> take_temporary_scrs()
312 {
313
1/2
✓ Branch 0 taken 27941 times.
✗ Branch 1 not taken.
27941 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
314
2/2
✓ Branch 0 taken 27941 times.
✓ Branch 1 taken 26599832 times.
26627773 for (int i = 0; i < 136*7; i++)
315 26599832 temporary_screens[i] = nullptr;
316
317 27941 return screens;
318
1/2
✓ Branch 0 taken 27941 times.
✗ Branch 1 not taken.
27941 }
319
320 14538258 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
321 {
322 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
323
324
2/2
✓ Branch 0 taken 14491676 times.
✓ Branch 1 taken 46582 times.
14538258 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
325 14538258 viewport.w = 256;
326 14538258 viewport.h = 176 + (extended_height_mode ? 56 : 0);
327
328
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14537898 times.
14538258 if (viewport_mode == ViewportMode::Script)
329 360 return;
330
331
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14491736 times.
14537898 if (!is_a_region(DMaps[dmap].map, screen))
332 {
333 14491736 viewport.x = 0;
334 14491736 viewport.y = 0;
335 14491736 }
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
337 {
338 // Clamp the viewport to the edges of the region.
339
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
340
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
341 46162 }
342 else if (viewport_mode == ViewportMode::Center)
343 {
344 viewport.x = x - viewport.w/2;
345 viewport.y = y - viewport.h/2;
346 }
347 14538258 }
348
349 14537747 sprite* get_viewport_sprite()
350 {
351 14537747 sprite* spr = sprite::getByUID(viewport_sprite_uid);
352
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14537741 times.
14537747 if (!spr)
353 {
354 6 viewport_sprite_uid = 1; // Hero uid.
355 6 spr = &Hero;
356 6 }
357
358 14537747 return spr;
359 }
360
361 6 void set_viewport_sprite(sprite* spr)
362 {
363 6 viewport_sprite_uid = spr->uid;
364 6 }
365
366 14509806 void update_viewport()
367 {
368 14509806 sprite* spr = get_viewport_sprite();
369 14509806 int x = spr->x + spr->txsz*16/2;
370 14509806 int y = spr->y + spr->tysz*16/2;
371 14509806 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
372 14509806 }
373
374 14297650 void update_heroscr()
375 {
376 void playLevelMusic();
377
378 14297650 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
379 14297650 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
380 14297650 int dx = x / 256;
381 14297650 int dy = y / 176;
382 14297650 int new_screen = cur_screen + dx + dy * 16;
383
2/2
✓ Branch 0 taken 14289888 times.
✓ Branch 1 taken 7762 times.
14297650 if (maze_state.active == 1)
384 7762 new_screen = maze_state.scr->screen;
385
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14297434 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14297650 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
386 {
387 216 region_scr_dx = dx;
388 216 region_scr_dy = dy;
389 216 hero_screen = new_screen;
390 216 prev_hero_scr = hero_scr;
391 216 hero_scr = get_scr(hero_screen);
392 216 Hero.screen_spawned = hero_screen;
393 216 playLevelMusic();
394 216 }
395
1/2
✓ Branch 0 taken 14297650 times.
✗ Branch 1 not taken.
14297650 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
396 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
397 14297650 }
398
399 4722 mapscr* determine_hero_screen_from_coords()
400 {
401 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
402 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
403 4722 int dx = x / 256;
404 4722 int dy = y / 176;
405 4722 return get_scr(cur_screen + dx + dy * 16);
406 }
407
408 26911 bool edge_of_region(direction dir)
409 {
410
2/2
✓ Branch 0 taken 26831 times.
✓ Branch 1 taken 80 times.
26911 if (!is_in_scrolling_region()) return true;
411
412 80 int screen_x = hero_screen % 16;
413 80 int screen_y = hero_screen / 16;
414
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
415
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
416
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
417
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
418
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
419 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
420 26911 }
421
422 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
423 // Coordinates are clamped to the world bounds.
424 211982041 int get_screen_for_world_xy(int x, int y)
425 {
426
2/2
✓ Branch 0 taken 189194949 times.
✓ Branch 1 taken 22787092 times.
211982041 if (!is_in_scrolling_region())
427 189194949 return cur_screen;
428
429 22787092 int dx = std::clamp(x, 0, world_w - 1) / 256;
430 22787092 int dy = std::clamp(y, 0, world_h - 1) / 176;
431 22787092 int origin_screen_x = cur_screen % 16;
432 22787092 int origin_screen_y = cur_screen / 16;
433 22787092 int scr_x = origin_screen_x + dx;
434 22787092 int scr_y = origin_screen_y + dy;
435 22787092 return map_scr_xy_to_index(scr_x, scr_y);
436 211982041 }
437
438 32518504 int get_screen_for_rpos(rpos_t rpos)
439 {
440 32518504 int origin_screen_x = cur_screen % 16;
441 32518504 int origin_screen_y = cur_screen / 16;
442 32518504 int screen = static_cast<int32_t>(rpos) / 176;
443 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
444 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
445 32518504 return map_scr_xy_to_index(scr_x, scr_y);
446 }
447
448 773455034 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
449 {
450 DCHECK_LAYER_ZERO_INDEX(layer);
451
2/2
✓ Branch 0 taken 741074490 times.
✓ Branch 1 taken 32380544 times.
773455034 if (!is_in_scrolling_region())
452 741074490 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
453 32380544 int screen = get_screen_for_rpos(rpos);
454 32380544 mapscr* scr = get_scr_layer(screen, layer);
455 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
456 773455034 }
457
458 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
459 // Coordinates are clamped to the world bounds.
460 3497025974 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
461 {
462 3497025974 x = std::clamp(x, 0, world_w - 1);
463 3497025974 y = std::clamp(y, 0, world_h - 1);
464
465 DCHECK_LAYER_ZERO_INDEX(layer);
466
2/2
✓ Branch 0 taken 3469288802 times.
✓ Branch 1 taken 27737172 times.
3497025974 if (!is_in_scrolling_region())
467 {
468 3469288802 int pos = COMBOPOS(x, y);
469 3469288802 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
470 }
471 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
472 3497025974 }
473
474 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
475 44 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
476 {
477 DCHECK_LAYER_ZERO_INDEX(layer);
478 44 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
479 }
480
481 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
482 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
483 62245 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
484 {
485 DCHECK_LAYER_ZERO_INDEX(layer);
486 62245 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
487 }
488
489 25143384 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
490 {
491 DCHECK_LAYER_ZERO_INDEX(layer);
492 25143384 rpos_handle.layer = layer;
493 25143384 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
494 25143384 }
495
496 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
497 // Coordinates are clamped to the world bounds.
498 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
499 {
500 DCHECK_LAYER_ZERO_INDEX(layer);
501
502 52808 x = std::clamp(x, 0, world_w - 1);
503 52808 y = std::clamp(y, 0, world_h - 1);
504
505 52808 auto maybe_ffc_handle = getFFCAt(x, y);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
507 return maybe_ffc_handle.value();
508
509 52808 auto rpos = COMBOPOS_REGION_B(x, y);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
511 return rpos_handle_t();
512 52808 return get_rpos_handle(rpos, layer);
513 52808 }
514
515 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
516 // directly or via zscript) only last until the next area is loaded (via loadscr).
517
518 // Returns the screen containing the (x, y) world position.
519 1632182317 mapscr* get_scr_for_world_xy(int x, int y)
520 {
521 // Quick path, but should work the same without.
522
2/2
✓ Branch 0 taken 1621050157 times.
✓ Branch 1 taken 11132160 times.
1632182317 if (!is_in_scrolling_region()) return origin_scr;
523 11132160 return get_scr(get_screen_for_world_xy(x, y));
524 1632182317 }
525
526 24481523 mapscr* get_scr_for_rpos(rpos_t rpos)
527 {
528 // Quick path, but should work the same without.
529
2/2
✓ Branch 0 taken 24343577 times.
✓ Branch 1 taken 137946 times.
24481523 if (!is_in_scrolling_region()) return origin_scr;
530 137946 return get_scr(get_screen_for_rpos(rpos));
531 24481523 }
532
533 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
534 {
535 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
536 }
537
538 // Note: layer=0 is the base screen, 1 is the first layer, etc.
539 2304409657 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
540 {
541 DCHECK_LAYER_ZERO_INDEX(layer);
542
2/2
✓ Branch 0 taken 2292992179 times.
✓ Branch 1 taken 11417478 times.
2304409657 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
543
2/2
✓ Branch 0 taken 708094 times.
✓ Branch 1 taken 10709384 times.
11417478 return layer == 0 ?
544 708094 get_scr_for_world_xy(x, y) :
545 10709384 get_scr_layer(get_screen_for_world_xy(x, y), layer);
546 2304409657 }
547
548 1830571890 int get_region_screen_offset(int screen)
549 {
550 1830571890 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
551 }
552
553 654673804 int get_screen_for_region_index_offset(int offset)
554 {
555 654673804 int scr_dx = offset % cur_region.screen_width;
556 654673804 int scr_dy = offset / cur_region.screen_width;
557 654673804 int screen = cur_screen + scr_dx + scr_dy*16;
558 654673804 return screen;
559 }
560
561 654489967 mapscr* get_scr_for_region_index_offset(int offset)
562 {
563 654489967 int screen = get_screen_for_region_index_offset(offset);
564 654489967 return get_scr(screen);
565 }
566
567 // The screen at (map, screen) must exist.
568 1419427809 mapscr* get_scr(int map, int screen)
569 {
570 1419427809 mapscr* scr = get_scr_maybe(map, screen);
571
1/2
✓ Branch 0 taken 1419427809 times.
✗ Branch 1 not taken.
1419427809 CHECK(scr);
572 1419427809 return scr;
573 }
574
575 837360004 mapscr* get_scr(int screen)
576 {
577 837360004 return get_scr(cur_map, screen);
578 }
579
580 // Returns null if active screen does not exist.
581 1448972576 mapscr* get_scr_maybe(int map, int screen)
582 {
583 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1448972576 times.
1448972576 if (map == cur_map)
586 {
587
2/2
✓ Branch 0 taken 1428199632 times.
✓ Branch 1 taken 20772944 times.
1448972576 if (screen == cur_screen)
588 1428199632 return origin_scr;
589
590 20772944 int index = screen*7;
591
2/2
✓ Branch 0 taken 20761854 times.
✓ Branch 1 taken 11090 times.
20772944 if (temporary_screens[index])
592 20761854 return temporary_screens[index];
593
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
595 return special_warp_return_scr;
596 11090 }
597
598
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
599 {
600 11090 int index = screen*7;
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
602 11090 return FFCore.ScrollingScreensAll[index];
603 }
604
605 return nullptr;
606 1448972576 }
607
608 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
609 7052568474 mapscr* get_scr_layer(int map, int screen, int layer)
610 {
611 DCHECK_LAYER_ZERO_INDEX(layer);
612
2/2
✓ Branch 0 taken 6471825393 times.
✓ Branch 1 taken 580743081 times.
7052568474 if (layer == 0)
613 580743081 return get_scr(map, screen);
614
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471825393 times.
6471825393 if (map == cur_map)
616 {
617 6471825393 int index = screen*7 + layer;
618
2/2
✓ Branch 0 taken 6471756993 times.
✓ Branch 1 taken 68400 times.
6471825393 if (temporary_screens[index])
619 6471756993 return temporary_screens[index];
620
621
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
622 1860 return &special_warp_return_scrs[layer];
623 66540 }
624
625
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
626 {
627 66540 int index = screen*7 + layer;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
629 66540 return FFCore.ScrollingScreensAll[index];
630 }
631
632 NOTREACHED();
633 7052568474 }
634
635 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
636 6653915901 mapscr* get_scr_layer(int screen, int layer)
637 {
638 6653915901 return get_scr_layer(cur_map, screen, layer);
639 }
640
641 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
642 // Return nullptr if screen is not valid.
643 396578848 mapscr* get_scr_layer_valid(int screen, int layer)
644 {
645
2/2
✓ Branch 0 taken 77993567 times.
✓ Branch 1 taken 318585281 times.
396578848 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
646 77993567 return scr;
647 318585281 return nullptr;
648 396578848 }
649
650 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
651 {
652 401 int x = get_region_relative_dx(screen);
653 401 int y = get_region_relative_dy(screen);
654
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
655 71 return nullptr;
656
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
657 return nullptr;
658
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
659 return nullptr;
660
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
661 189 return nullptr;
662
663 141 screen = screen_index_direction(screen, dir);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
665 return get_scr(screen);
666
667 141 return nullptr;
668 401 }
669
670 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
671 {
672 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
673 183837 uint8_t i = id % MAXFFCS;
674 183837 mapscr* scr = get_scr(screen);
675 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
676 183837 return {scr, screen, id, i, ffc};
677 }
678
679 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
680 {
681 34566 x += get_region_relative_dx(screen) * 256;
682 34566 y += get_region_relative_dy(screen) * 176;
683 34566 return {x, y};
684 }
685
686 1049392 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
687 {
688 1049392 int x = get_region_relative_dx(screen) * 256;
689 1049392 int y = get_region_relative_dy(screen) * 176;
690 1049392 return {x, y};
691 }
692
693 12122271950 int32_t COMBOPOS(int32_t x, int32_t y)
694 {
695 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
696 12122271950 return (y & 0xF0) + (x >> 4);
697 }
698 int32_t COMBOPOS_B(int32_t x, int32_t y)
699 {
700 if(unsigned(x) >= 256 || unsigned(y) >= 176)
701 return -1;
702 return (y & 0xF0) + (x >> 4);
703 }
704 3323914272 int32_t COMBOX(int32_t pos)
705 {
706 3323914272 return pos % 16 * 16;
707 }
708 3323914272 int32_t COMBOY(int32_t pos)
709 {
710 3323914272 return pos & 0xF0;
711 }
712
713 112491539 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
714 {
715
2/2
✓ Branch 0 taken 83938893 times.
✓ Branch 1 taken 28552646 times.
112491539 if (!is_in_scrolling_region())
716 83938893 return (rpos_t) COMBOPOS(x, y);
717
718 DCHECK(is_in_world_bounds(x, y));
719 28552646 int scr_dx = x / (16*16);
720 28552646 int scr_dy = y / (11*16);
721 28552646 int pos = COMBOPOS(x%256, y%176);
722 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
723 112491539 }
724 6295880580 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
725 {
726
2/2
✓ Branch 0 taken 1397544 times.
✓ Branch 1 taken 6294483036 times.
6295880580 if (!is_in_world_bounds(x, y))
727 1397544 return rpos_t::None;
728
729 6294483036 int scr_dx = x / (16*16);
730 6294483036 int scr_dy = y / (11*16);
731 6294483036 int pos = COMBOPOS(x%256, y%176);
732 6294483036 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 6295880580 }
734 21459328 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
735 {
736 21459328 int scr_index = static_cast<int32_t>(rpos) / 176;
737 21459328 int scr_dx = scr_index % cur_region.screen_width;
738 21459328 int scr_dy = scr_index / cur_region.screen_width;
739 21459328 int pos = RPOS_TO_POS(rpos);
740 21459328 int x = scr_dx*16*16 + COMBOX(pos);
741 21459328 int y = scr_dy*11*16 + COMBOY(pos);
742 21459328 return {x, y};
743 }
744 60396 int32_t COMBOX_REGION(rpos_t rpos)
745 {
746 60396 auto [x, y] = COMBOXY_REGION(rpos);
747 60396 return x;
748 }
749 12225 int32_t COMBOY_REGION(rpos_t rpos)
750 {
751 12225 auto [x, y] = COMBOXY_REGION(rpos);
752 12225 return y;
753 }
754
755 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
756 {
757 DCHECK(is_in_world_bounds(x, y));
758
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
759 70177 return (rpos_t)(x + y * 16);
760
761 int scr_dx = x / 16;
762 int scr_dy = y / 11;
763 x %= 16;
764 y %= 11;
765 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
766 70177 }
767 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
768 {
769 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
770 70632 int scr_dx = scr_index % cur_region.screen_width;
771 70632 int scr_dy = scr_index / cur_region.screen_width;
772 70632 int pos = RPOS_TO_POS(rpos);
773 70632 int x = scr_dx*16 + pos%16;
774 70632 int y = scr_dy*11 + pos/16;
775 70632 return {x, y};
776 }
777
778 553576679 int32_t mapind(int32_t map, int32_t scr)
779 {
780 553576679 return map * MAPSCRSNORMAL + scr;
781 }
782
783 FONT *get_zc_font(int index);
784
785 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
786 extern movingblock mblock2; //mblock[4]?
787 extern portal mirror_portal;
788
789 void Z_message_d(const char *format,...)
790 {
791 #ifdef _DEBUG
792 char buf[512];
793 va_list ap;
794 va_start(ap, format);
795 vsprintf(buf, format, ap);
796 va_end(ap);
797
798 al_trace("%s",buf);
799 #else
800 format=format;
801 #endif
802 }
803
804
805
806 bool checktrigger=false;
807
808 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
809 {
810 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
811 int32_t index = script_drawing_commands.GetNext();
812
813 if(index < 0)
814 return;
815
816 int32_t *sdci = &script_drawing_commands[index][0];
817
818 sdci[0] = RECTR;
819 sdci[1] = 30000;
820 sdci[2] = x1*10000;
821 sdci[3] = y1*10000;
822 sdci[4] = x2*10000;
823 sdci[5] = y2*10000;
824 sdci[6] = 10000;
825 sdci[7] = 10000;
826 sdci[8] = 0;
827 sdci[9] = 0;
828 sdci[10] = 0;
829 sdci[11] = 10000;
830 sdci[12] = 1280000;
831 }
832
833 void clear_dmap(word i)
834 {
835 DMaps[i].clear();
836 }
837
838 void clear_dmaps()
839 {
840 for(int32_t i=0; i<MAXDMAPS; i++)
841 {
842 clear_dmap(i);
843 }
844 }
845
846 223418082 int32_t isdungeon(int32_t dmap, int32_t screen)
847 {
848
2/2
✓ Branch 0 taken 223372402 times.
✓ Branch 1 taken 45680 times.
223418082 if (dmap < 0) dmap = cur_dmap;
849
850 // dungeons can have any dlevel above 0
851
2/2
✓ Branch 0 taken 122175146 times.
✓ Branch 1 taken 101242936 times.
223418082 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
852 {
853
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101232975 times.
101242936 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
854 9961 return 0;
855
856 101232975 return 1;
857 }
858
859 // dlevels that aren't dungeons are caves
860
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122138319 times.
122175146 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
861 36827 return 1;
862
863 122138319 return 0;
864 223418082 }
865
866 39924269 int32_t isdungeon(int32_t screen)
867 {
868 39924269 return isdungeon(cur_dmap, screen);
869 }
870
871 183366931 int32_t isdungeon()
872 {
873 183366931 return isdungeon(cur_dmap, hero_screen);
874 }
875
876 88901 bool canPermSecret(int32_t dmap, int32_t screen)
877 {
878
2/2
✓ Branch 0 taken 13909 times.
✓ Branch 1 taken 74992 times.
88901 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
879 }
880
881 1374206809 int32_t MAPCOMBO(int32_t x, int32_t y)
882 {
883 1374206809 x = vbound(x, 0, world_w-1);
884 1374206809 y = vbound(y, 0, world_h-1);
885 1374206809 int pos = COMBOPOS(x%256, y%176);
886 1374206809 mapscr* scr = get_scr_for_world_xy(x, y);
887 1374206809 return scr->data[pos];
888 }
889
890 //specific layers 1 to 6
891 1707746039 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
892 {
893 DCHECK(layer >= 1 && layer <= 6);
894
3/4
✓ Branch 0 taken 1687395973 times.
✓ Branch 1 taken 20350066 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1687395973 times.
1707746039 if (!is_in_world_bounds(x, y) || layer <= 0)
895 20350066 return 0;
896
897 1687395973 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
898
2/2
✓ Branch 0 taken 495770603 times.
✓ Branch 1 taken 1191625370 times.
1687395973 if (!m->is_valid())
899 1191625370 return 0;
900
901 495770603 int pos = COMBOPOS(x%256, y%176);
902 495770603 return m->data[pos];
903 1707746039 }
904
905 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
906 {
907 DCHECK(layer >= 1 && layer <= 6);
908 if (!is_in_world_bounds(x, y) || layer <= 0)
909 return 0;
910
911 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
912 if (!m->is_valid())
913 return 0;
914
915 int pos = COMBOPOS(x%256, y%176);
916 return m->cset[pos];
917 }
918
919 189084 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
2/4
✓ Branch 0 taken 189084 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189084 times.
189084 if (!is_in_world_bounds(x, y) || layer <= 0)
923 return 0;
924
925 189084 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 148690 times.
✓ Branch 1 taken 40394 times.
189084 if (!m->is_valid())
927 40394 return 0;
928
929 148690 int pos = COMBOPOS(x%256, y%176);
930 148690 return m->sflag[pos];
931 189084 }
932
933 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
941 472 return 0;
942
943 5809 int pos = COMBOPOS(x%256, y%176);
944 5809 return combobuf[m->data[pos]].type;
945 6281 }
946
947 189084 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189084 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189084 times.
189084 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189084 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148690 times.
✓ Branch 1 taken 40394 times.
189084 if (!m->is_valid())
955 40394 return 0;
956
957 148690 int pos = COMBOPOS(x%256, y%176);
958 148690 return combobuf[m->data[pos]].flag;
959 189084 }
960
961
962 // True if the FFC covers x, y and is not ethereal or a changer.
963 2467131926 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
964 {
965
2/2
✓ Branch 0 taken 746693882 times.
✓ Branch 1 taken 1720438044 times.
2467131926 if (ffc_handle.data()<=0)
966 746693882 return false;
967
968
2/2
✓ Branch 0 taken 300864173 times.
✓ Branch 1 taken 1419573871 times.
1720438044 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
969 300864173 return false;
970
971 1419573871 int32_t fx=ffc_handle.ffc->x.getInt();
972
4/4
✓ Branch 0 taken 976065666 times.
✓ Branch 1 taken 443508205 times.
✓ Branch 2 taken 865966839 times.
✓ Branch 3 taken 110098827 times.
1419573871 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
973 1309475044 return false;
974
975 110098827 int32_t fy=ffc_handle.ffc->y.getInt();
976
4/4
✓ Branch 0 taken 80119168 times.
✓ Branch 1 taken 29979659 times.
✓ Branch 2 taken 60053743 times.
✓ Branch 3 taken 20065425 times.
110098827 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
977 90033402 return false;
978
979 20065425 return true;
980 2467131926 }
981
982 998057692 int32_t MAPFFCOMBO(int32_t x,int32_t y)
983 {
984
2/2
✓ Branch 0 taken 13161290 times.
✓ Branch 1 taken 984896402 times.
998057692 if (auto ffc_handle = getFFCAt(x, y))
985 13161290 return ffc_handle->data();
986 984896402 return 0;
987 998057692 }
988
989 207232 int32_t MAPCSET(int32_t x, int32_t y)
990 {
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
992 return 0;
993 207232 mapscr* scr = get_scr_for_world_xy(x, y);
994 207232 int pos = COMBOPOS(x%256, y%176);
995 207232 return scr->cset[pos];
996 207232 }
997
998 73651503 int32_t MAPFLAG(int32_t x, int32_t y)
999 {
1000
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73623363 times.
73651503 if (!is_in_world_bounds(x, y))
1001 28140 return 0;
1002 73623363 mapscr* scr = get_scr_for_world_xy(x, y);
1003 73623363 int pos = COMBOPOS(x%256, y%176);
1004 73623363 return scr->sflag[pos];
1005 73651503 }
1006
1007 165692612 int32_t COMBOTYPE(int32_t x,int32_t y)
1008 {
1009 165692612 int32_t b=1;
1010
2/2
✓ Branch 0 taken 96754421 times.
✓ Branch 1 taken 68938191 times.
165692612 if(x&8) b<<=2;
1011
2/2
✓ Branch 0 taken 83455899 times.
✓ Branch 1 taken 82236713 times.
165692612 if(y&8) b<<=1;
1012
1013
2/2
✓ Branch 0 taken 331378186 times.
✓ Branch 1 taken 165685574 times.
497063760 for (int32_t i = 0; i <= 1; ++i)
1014 {
1015
2/2
✓ Branch 0 taken 320233226 times.
✓ Branch 1 taken 11144960 times.
331378186 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320233226 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
320233226 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1018 320233226 }
1019 else
1020 {
1021
4/4
✓ Branch 0 taken 10190 times.
✓ Branch 1 taken 11134770 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7038 times.
11144960 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1022 }
1023 331371148 }
1024
1025 165685574 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1026
5/6
✓ Branch 0 taken 3652644 times.
✓ Branch 1 taken 162032930 times.
✓ Branch 2 taken 3069708 times.
✓ Branch 3 taken 582936 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3069708 times.
165685574 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1027 {
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069708 times.
3069708 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069708 times.
3069708 if(cmb.usrflags&cflag3) return cNONE;
1030 3069708 }
1031 165685574 return cmb.type;
1032 165692612 }
1033
1034 50218236 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1035 {
1036 50218236 return combobuf[MAPFFCOMBO(x,y)].type;
1037 }
1038
1039 4915492 int32_t FFORCOMBO(int32_t x, int32_t y)
1040 {
1041
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4856976 times.
4915492 if (auto ffc_handle = getFFCAt(x, y))
1042 58516 return ffc_handle->data();
1043
1044 4856976 return MAPCOMBO(x,y);
1045 4915492 }
1046
1047 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1048 {
1049 for (int32_t i = 0; i <= 1; ++i)
1050 {
1051 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1052 {
1053 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1054 }
1055 else
1056 {
1057 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1058 }
1059 }
1060 int32_t b=1;
1061
1062 if(x&8) b<<=2;
1063
1064 if(y&8) b<<=1;
1065 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1066 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1067 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1068 return cmb.type;
1069 }
1070
1071 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1072 {
1073 if (auto ffc_handle = getFFCAt(x, y))
1074 return ffc_handle->data();
1075
1076 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1077 }
1078
1079 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1080 {
1081 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1082 }
1083
1084 70141903 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1085 {
1086
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70114051 times.
70141903 if (!is_in_world_bounds(x, y))
1087 27852 return 0;
1088
1089 70114051 mapscr* scr = get_scr_for_world_xy(x, y);
1090 70114051 int pos = COMBOPOS(x%256, y%176);
1091 70114051 return combobuf[scr->data[pos]].flag;
1092 70141903 }
1093
1094 56824297 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56078120 times.
56824297 if (auto ffc_handle = getFFCAt(x, y))
1097 746177 return ffc_handle->cflag();
1098
1099 56078120 return 0;
1100 56824297 }
1101
1102 1311633735 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1103 {
1104 2787069343 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1105 1475435608 return ffcIsAt(ffc_handle, x, y);
1106 });
1107 }
1108
1109 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1110 {
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1112 3044 return rpos_handle.data();
1113 3044 }
1114
1115 3163902445 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1116 {
1117 DCHECK_LAYER_NEG1_INDEX(layer);
1118
2/2
✓ Branch 0 taken 22416514 times.
✓ Branch 1 taken 3141485931 times.
3163902445 if (!is_in_world_bounds(x, y)) return 0;
1119
2/2
✓ Branch 0 taken 3072666197 times.
✓ Branch 1 taken 68819734 times.
3141485931 if (layer == -1) return MAPCOMBO(x, y);
1120
1121 3072666197 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1122
2/2
✓ Branch 0 taken 2117368007 times.
✓ Branch 1 taken 955298190 times.
3072666197 if (!rpos_handle.scr->is_valid()) return 0;
1123
1124 955298190 return rpos_handle.data();
1125 3163902445 }
1126
1127 15796 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1128 {
1129 15796 auto screen_handles = create_screen_handles_one(&scr);
1130
1131
3/4
✓ Branch 0 taken 535 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 535 times.
15796 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1132 {
1133 535 reveal_hidden_stairs(&scr, screen, false);
1134 535 bool do_layers = false;
1135 535 bool from_active_screen = false;
1136 535 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1137 535 }
1138
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if (flags & mLIGHTBEAM)
1139 {
1140 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1141 if (rpos_handle.ctype() == cLIGHTTARGET)
1142 {
1143 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1144 rpos_handle.increment_data();
1145 }
1146 });
1147 }
1148
1149 15796 int lvl = DMaps[cur_dmap].level;
1150 15796 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1151 15796 toggle_gswitches_load(screen_handles);
1152
1153
2/2
✓ Branch 0 taken 15704 times.
✓ Branch 1 taken 92 times.
15796 if(flags&mLOCKBLOCK) // if special stuff done before
1154 {
1155 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1156 92 }
1157
1158
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1159 {
1160 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1161 }
1162
1163
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mCHEST) // if special stuff done before
1164 {
1165 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1166 }
1167
1168
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mCHEST) // if special stuff done before
1169 {
1170 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1171 }
1172
1173
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mBOSSCHEST) // if special stuff done before
1174 {
1175 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1176 }
1177
1178
1179 15796 int mi = mapind(map, screen);
1180 15796 clear_xdoors_mi(screen_handles, mi);
1181 15796 clear_xstatecombos_mi(screen_handles, mi);
1182
1183 2797652 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
1184 // This is duplicated 3 places... can this be reduced?
1185 2781856 auto cid = handle.data();
1186 2781856 auto* cmb = &handle.combo();
1187 2781856 bool done = false;
1188 2781856 std::set<int32_t> visited;
1189
2/4
✓ Branch 0 taken 2781856 times.
✓ Branch 1 taken 2781856 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5563712 while(!done)
1190 {
1191
2/8
✓ Branch 0 taken 2781856 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2781856 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2781856 if(visited.contains(cid))
1192 {
1193 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1194 break; // prevent infinite loop
1195 }
1196
1/4
✓ Branch 0 taken 2781856 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2781856 visited.insert(cid);
1197
1198 2781856 done = true; // don't loop again unless something changes
1199
2/4
✓ Branch 0 taken 2781856 times.
✓ Branch 1 taken 41380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2823236 for(size_t idx = 0; idx < cmb->triggers.size(); ++idx)
1200 {
1201 41380 auto& trig = cmb->triggers[idx];
1202
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 41380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
41380 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
1203 do_trigger_combo(handle, idx);
1204 41380 else continue; // can skip checking handle.data()
1205
1206 if(handle.data() != cid)
1207 {
1208 cid = handle.data();
1209 cmb = &handle.combo();
1210 done = false; // loop again for the new combo
1211 break;
1212 }
1213 }
1214 }
1215 2781856 });
1216 15796 }
1217
1218 53166 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1219 {
1220
2/4
✓ Branch 0 taken 53166 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53166 times.
53166 if (map < 0 || screen < 0)
1221 return std::nullopt;
1222
1223 53166 const mapscr* source = get_canonical_scr(map, screen);
1224
2/2
✓ Branch 0 taken 40953 times.
✓ Branch 1 taken 12213 times.
53166 if (!source->is_valid())
1225 12213 return std::nullopt;
1226
1227
2/2
✓ Branch 0 taken 8307 times.
✓ Branch 1 taken 32646 times.
40953 if (layer >= 0)
1228 {
1229
2/2
✓ Branch 0 taken 25157 times.
✓ Branch 1 taken 7489 times.
32646 if (source->layermap[layer] <= 0)
1230 25157 return std::nullopt;
1231
1232 7489 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1233
1/2
✓ Branch 0 taken 7489 times.
✗ Branch 1 not taken.
7489 if (!source->is_valid())
1234 return std::nullopt;
1235 7489 }
1236
1237
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1238 15796 mapscr scr = *source;
1239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15796 times.
15796 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1240
1241 15796 return scr;
1242 53166 }
1243
1244 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1245 {
1246
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1247
1248
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1249 return 0;
1250
1251 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1252 // `apply_state_changes_to_screen` checks).
1253
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1254 4976 return s->data[pos];
1255
1256 22227 return 0;
1257 27203 }
1258
1259 // Read from the current temporary screens or, if (map, screen) is not loaded,
1260 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1261 136554394 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1262 {
1263 DCHECK_LAYER_NEG1_INDEX(layer);
1264 DCHECK(map >= 0 && screen >= 0);
1265
1266
2/2
✓ Branch 0 taken 136527191 times.
✓ Branch 1 taken 27203 times.
136554394 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1267
1268 // Screen is not in the current region, so we have to load and trigger some secrets.
1269 27203 int pos = COMBOPOS(x, y);
1270 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1271 136554394 }
1272
1273 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1274 {
1275 DCHECK_LAYER_NEG1_INDEX(layer);
1276 DCHECK(map >= 0 && screen >= 0);
1277 DCHECK(is_valid_rpos(rpos));
1278
1279 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1280
1281 // Screen is not currently loaded, so we have to load and trigger some secrets.
1282 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1283 }
1284
1285 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1286 {
1287 DCHECK_LAYER_NEG1_INDEX(layer);
1288 if (!is_in_world_bounds(x, y))
1289 return 0;
1290 if (layer == -1) return MAPCSET(x, y);
1291
1292 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1293 if (!rpos_handle.scr->is_valid()) return 0;
1294
1295 return rpos_handle.cset();
1296 }
1297
1298 98886311 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1299 {
1300 DCHECK_LAYER_NEG1_INDEX(layer);
1301
3/4
✓ Branch 0 taken 1861685 times.
✓ Branch 1 taken 97024626 times.
✓ Branch 2 taken 1861685 times.
✗ Branch 3 not taken.
98886311 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1302 return 0;
1303
2/2
✓ Branch 0 taken 81284683 times.
✓ Branch 1 taken 17601628 times.
98886311 if (layer == -1) return MAPFLAG(x, y);
1304
1305 81284683 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1306
2/2
✓ Branch 0 taken 62992546 times.
✓ Branch 1 taken 18292137 times.
81284683 if (!rpos_handle.scr->is_valid()) return 0;
1307
1308 18292137 return rpos_handle.sflag();
1309 98886311 }
1310
1311 2518104 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1312 {
1313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2518104 times.
2518104 if(layer < 1)
1314 {
1315
2/2
✓ Branch 0 taken 5036208 times.
✓ Branch 1 taken 2518104 times.
7554312 for (int32_t i = layer+1; i <= 1; ++i)
1316 {
1317
2/2
✓ Branch 0 taken 4212456 times.
✓ Branch 1 taken 823752 times.
5036208 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1318 {
1319
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4212456 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4212456 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1320 4212456 }
1321 else
1322 {
1323
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 823752 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
823752 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1324 }
1325 5036208 }
1326 2518104 }
1327
1/2
✓ Branch 0 taken 2518104 times.
✗ Branch 1 not taken.
2518104 if(layer==-1) return COMBOTYPE(x,y);
1328
1329 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1330 if (!rpos_handle.scr->is_valid()) return 0;
1331
1332 return rpos_handle.ctype();
1333 2518104 }
1334
1335 // Returns the flag for the combo at the given position.
1336 // This is also known as an "inherent flag".
1337 97118292 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1338 {
1339 DCHECK_LAYER_NEG1_INDEX(layer);
1340
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97118004 times.
97118292 if (!is_in_world_bounds(x, y))
1341 288 return 0;
1342
2/2
✓ Branch 0 taken 81226602 times.
✓ Branch 1 taken 15891402 times.
97118004 if (layer == -1) return MAPCOMBOFLAG(x, y);
1343
1344 81226602 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1345
2/2
✓ Branch 0 taken 63002459 times.
✓ Branch 1 taken 18224143 times.
81226602 if (!rpos_handle.scr->is_valid()) return 0;
1346
1347 18224143 return rpos_handle.cflag();
1348 97118292 }
1349
1350 11415939 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1351 {
1352 DCHECK_LAYER_ZERO_INDEX(layer);
1353 11415939 auto rpos_handle = get_rpos_handle(rpos, layer);
1354
2/2
✓ Branch 0 taken 6344284 times.
✓ Branch 1 taken 5071655 times.
11415939 if (!rpos_handle.scr->is_valid()) return false;
1355
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5067090 times.
5071655 if (rpos_handle.sflag() == flag) return true;
1356
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5029385 times.
5067090 if (rpos_handle.cflag() == flag) return true;
1357 5029385 return false;
1358 11415939 }
1359
1360 1666933 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1361 {
1362 DCHECK(is_valid_rpos(rpos));
1363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1666933 times.
1666933 if (rpos > region_max_rpos) return false;
1364
1365
2/2
✓ Branch 0 taken 11415939 times.
✓ Branch 1 taken 1624663 times.
13040602 for(auto q = 0; q < 7; ++q)
1366 {
1367
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11373669 times.
11415939 if(HASFLAG(flag, q, rpos))
1368 42270 return true;
1369 11373669 }
1370 1624663 return false;
1371 1666933 }
1372
1373 const char *screenstate_string[16] =
1374 {
1375 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "No Return",
1376 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1377 "Boss Locked Chests", "Secrets", "Visited", "Light Beams"
1378 };
1379
1380 34843 void eventlog_mapflags()
1381 {
1382 34843 std::ostringstream oss;
1383
1384 34843 int mi = mapind(cur_map, home_screen);
1385
1/2
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
34843 word g = game->maps[mi] &0x3FFF;
1386
1387
2/4
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34843 times.
✗ Branch 3 not taken.
34843 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1388
2/2
✓ Branch 0 taken 7049 times.
✓ Branch 1 taken 27794 times.
34843 if(g) // Main States
1389 {
1390 static const int order[] =
1391 {
1392 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1393 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1394 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1395 mNEVERRET, mTMPNORET
1396 };
1397
1398
1/2
✓ Branch 0 taken 7049 times.
✗ Branch 1 not taken.
7049 oss << " [";
1399 7049 bool comma = false;
1400
2/2
✓ Branch 0 taken 7049 times.
✓ Branch 1 taken 98686 times.
105735 for(int fl : order)
1401 {
1402
2/2
✓ Branch 0 taken 8967 times.
✓ Branch 1 taken 89719 times.
98686 if(!(g&fl))
1403 89719 continue;
1404 8967 byte ind = byte(log2(double(fl)));
1405
2/2
✓ Branch 0 taken 1918 times.
✓ Branch 1 taken 7049 times.
8967 if(comma)
1406
1/2
✓ Branch 0 taken 1918 times.
✗ Branch 1 not taken.
1918 oss << ", ";
1407
1/2
✓ Branch 0 taken 8967 times.
✗ Branch 1 not taken.
8967 oss << screenstate_string[ind];
1408 8967 comma = true;
1409 }
1410
1/2
✓ Branch 0 taken 7049 times.
✗ Branch 1 not taken.
7049 oss << "]";
1411 7049 }
1412
3/4
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 34811 times.
34843 if(game->xstates[mi]) // ExStates
1413 {
1414
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 oss << " Ex[";
1415 32 bool comma = false;
1416
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1024 times.
1056 for(byte fl = 0; fl < 32; ++fl)
1417 {
1418
3/4
✓ Branch 0 taken 1024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 992 times.
1024 if(game->xstates[mi] & (1<<fl))
1419 {
1420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if(comma)
1421 oss << ", ";
1422
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 oss << int(fl);
1423 32 comma = true;
1424 32 }
1425 1024 }
1426
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 oss << "]";
1427 32 }
1428 { // ExDoors
1429
2/2
✓ Branch 0 taken 34843 times.
✓ Branch 1 taken 139372 times.
174215 for(int q = 0; q < 4; ++q)
1430 {
1431 139372 bool comma = false;
1432
2/4
✓ Branch 0 taken 139372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139372 times.
✗ Branch 3 not taken.
139372 if(auto v = game->xdoors[mi][q])
1433 {
1434 if(comma)
1435 oss << ",";
1436 else oss << " ExDoor";
1437 oss << "[" << dirstr[q];
1438 for(int fl = 0; fl < 8; ++fl)
1439 if(v & (1<<fl))
1440 oss << " " << int(fl);
1441 oss << "]";
1442 comma = true;
1443 }
1444 139372 }
1445 }
1446
2/4
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34843 times.
34843 Z_eventlog("%s\n", oss.str().c_str());
1447 34843 }
1448
1449 // set specific flag
1450 5608 void setmapflag(mapscr* scr, int32_t flag)
1451 {
1452
2/2
✓ Branch 0 taken 5595 times.
✓ Branch 1 taken 13 times.
5608 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1453 5608 int mi = mapind(cur_map, scr->screen);
1454 5608 setmapflag_mi(scr, mi, flag);
1455 5608 }
1456 57 void setmapflag_homescr(int32_t flag)
1457 {
1458 57 int mi = mapind(cur_map, home_screen);
1459 57 setmapflag_mi(origin_scr, mi, flag);
1460 57 }
1461 2023 void setmapflag_mi(int32_t mi, int32_t flag)
1462 {
1463 2023 byte cscr = mi&((1<<7)-1);
1464 2023 byte cmap = (mi>>7);
1465 2023 mapscr* scr = origin_scr;
1466
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1467 1189 scr = get_scr(cmap, cscr);
1468
1469 2023 setmapflag_mi(scr, mi, flag);
1470 2023 }
1471
1472 8459 static void log_state_change(int map, int screen, std::string action)
1473 {
1474
6/6
✓ Branch 0 taken 1911 times.
✓ Branch 1 taken 6548 times.
✓ Branch 2 taken 994 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 642 times.
8459 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1475 6900 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1476 else
1477 1559 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1478 8459 }
1479
1480 7688 void setmapflag_mi(mapscr* scr, int32_t mi, int32_t flag)
1481 {
1482 7688 byte cscr = mi&((1<<7)-1);
1483 7688 byte cmap = (mi>>7);
1484
1485 7688 float temp=log2((float)flag);
1486
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7688 times.
7688 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1487
1488
3/4
✓ Branch 0 taken 7688 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6136 times.
7688 if (replay_is_active() && !(game->maps[mi] & flag))
1489
1/2
✓ Branch 0 taken 6136 times.
✗ Branch 1 not taken.
6136 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, state_string));
1490 7688 game->maps[mi] |= flag;
1491
1/2
✓ Branch 0 taken 7688 times.
✗ Branch 1 not taken.
7688 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1492
1493
10/10
✓ Branch 0 taken 5451 times.
✓ Branch 1 taken 2237 times.
✓ Branch 2 taken 3614 times.
✓ Branch 3 taken 1837 times.
✓ Branch 4 taken 3031 times.
✓ Branch 5 taken 583 times.
✓ Branch 6 taken 2877 times.
✓ Branch 7 taken 154 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 2480 times.
10181 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1494
6/6
✓ Branch 0 taken 2830 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2685 times.
✓ Branch 3 taken 145 times.
✓ Branch 4 taken 2493 times.
✓ Branch 5 taken 192 times.
2877 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1495 {
1496 5208 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1497 5208 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1498
1499 5208 std::vector<int32_t> done;
1500
2/2
✓ Branch 0 taken 5093 times.
✓ Branch 1 taken 115 times.
5208 bool looped = (nmap==cmap+1 && nscr==cscr);
1501
1502
6/6
✓ Branch 0 taken 538 times.
✓ Branch 1 taken 5156 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 486 times.
✓ Branch 4 taken 486 times.
✓ Branch 5 taken 5208 times.
5694 while((nmap!=0) && !looped && !(nscr>=128))
1503 {
1504
5/6
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 364 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 171 times.
✓ Branch 5 taken 193 times.
486 if((scr->nocarry&flag)!=flag && !(game->maps[((nmap-1)<<7)+nscr] & flag))
1505 {
1506
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1507
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1508
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, state_string));
1509
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1510 193 }
1511
1512 486 cmap=nmap;
1513 486 cscr=nscr;
1514 486 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1515 486 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1516
1517
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 486 times.
1966 for(auto it = done.begin(); it != done.end(); it++)
1518 {
1519
2/2
✓ Branch 0 taken 1428 times.
✓ Branch 1 taken 52 times.
1480 if(*it == ((nmap-1)<<7)+nscr)
1520 52 looped = true;
1521 1480 }
1522
1523
1/2
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
486 done.push_back(((nmap-1)<<7)+nscr);
1524 }
1525 5208 }
1526 7688 }
1527
1528 void unsetmapflag_home(int32_t flag, bool anyflag)
1529 {
1530 int mi = mapind(cur_map, home_screen);
1531 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1532 }
1533
1534 void unsetmapflag(mapscr* scr, int32_t flag, bool anyflag)
1535 {
1536 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1537 int mi = mapind(cur_map, scr->screen);
1538 unsetmapflag_mi(scr, mi, flag, anyflag);
1539 }
1540
1541 471 void unsetmapflag_mi(int32_t mi, int32_t flag, bool anyflag)
1542 {
1543 471 byte cscr = mi&((1<<7)-1);
1544 471 byte cmap = (mi>>7);
1545 471 mapscr* scr = origin_scr;
1546
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1547 11 scr = get_scr(cmap, cscr);
1548
1549 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1550 471 }
1551
1552 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, int32_t flag, bool anyflag)
1553 {
1554 471 byte cscr = mi&((1<<7)-1);
1555 471 byte cmap = (mi>>7);
1556
1557
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1558 460 game->maps[mi] &= ~flag;
1559
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1560 {
1561 if(!(scr->flags4&fNOITEMRESET))
1562 game->maps[mi] &= ~flag;
1563 }
1564 11 else game->maps[mi] &= ~flag;
1565
1566 471 float temp=log2((float)flag);
1567
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1568
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1569
1570
5/10
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 460 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
471 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1571
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
11 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1572 {
1573 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1574 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1575
1576 471 std::vector<int32_t> done;
1577
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1578
1579
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1580 {
1581
4/6
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 72 times.
84 if((scr->nocarry&flag)!=flag && (game->maps[((nmap-1)<<7)+nscr] & flag))
1582 {
1583
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1584
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1585 72 }
1586
1587 84 cmap=nmap;
1588 84 cscr=nscr;
1589 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1590 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1591
1592
2/2
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 84 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1593 {
1594
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1595 6 looped = true;
1596 546 }
1597
1598
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1599 }
1600 471 }
1601 471 }
1602
1603 44151379 bool getmapflag(int32_t screen, int32_t flag)
1604 {
1605
2/2
✓ Branch 0 taken 1164399 times.
✓ Branch 1 taken 42986980 times.
44151379 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1606 44151379 return (game->maps[mi] & flag) != 0;
1607 }
1608 162323 bool getmapflag(mapscr* scr, int32_t flag)
1609 {
1610 162323 return getmapflag(scr->screen, flag);
1611 }
1612
1613 59 void setxmapflag(int32_t screen, uint32_t flag)
1614 {
1615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1616 59 setxmapflag_mi(mi, flag);
1617 59 }
1618 61 void setxmapflag_mi(int32_t mi, uint32_t flag)
1619 {
1620
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 35 times.
61 if(game->xstates[mi] & flag) return;
1621 35 byte cscr = mi&((1<<7)-1);
1622 35 byte cmap = (mi>>7);
1623
1624 35 byte temp=(byte)log2((double)flag);
1625
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1626
1627 35 game->xstates[mi] |= flag;
1628 61 }
1629 void unsetxmapflag(int32_t screen, uint32_t flag)
1630 {
1631 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1632 unsetxmapflag_mi(mi, flag);
1633 }
1634 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1635 {
1636 if(!(game->xstates[mi] & flag)) return;
1637 byte cscr = mi&((1<<7)-1);
1638 byte cmap = (mi>>7);
1639 byte temp=(byte)log2((double)flag);
1640 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1641 game->xstates[mi] &= ~flag;
1642 }
1643 bool getxmapflag(int32_t screen, uint32_t flag)
1644 {
1645 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1646 return getxmapflag_mi(mi, flag);
1647 }
1648 471118798 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1649 {
1650 471118798 return (game->xstates[mi] & flag) != 0;
1651 }
1652
1653 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1654 {
1655 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1656 return;
1657 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1658 return;
1659
1660 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1661
1662 int cscr = mi % MAPSCRSNORMAL;
1663 int cmap = mi / MAPSCRSNORMAL;
1664 if (state)
1665 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1666 else
1667 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1668 }
1669 471118784 bool getxdoor_mi(uint mi, uint dir, uint ind)
1670 {
1671
5/6
✓ Branch 0 taken 471118784 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2582048 times.
✓ Branch 3 taken 468536736 times.
✓ Branch 4 taken 1936536 times.
✓ Branch 5 taken 645512 times.
471118784 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1672 470473272 return false;
1673 645512 return (game->xdoors[mi][dir] & (1<<ind));
1674 471118784 }
1675 bool getxdoor(int32_t screen, uint dir, uint ind)
1676 {
1677 int mi = mapind(cur_map, screen);
1678 return getxdoor_mi(mi,dir,ind);
1679 }
1680
1681 401 void set_doorstate_mi(uint mi, uint dir)
1682 {
1683
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1684 return;
1685 401 setmapflag_mi(mi, mDOOR_UP << dir);
1686
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1687 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1688 401 }
1689 401 void set_doorstate(uint screen, uint dir)
1690 {
1691 401 int mi = mapind(cur_map, screen);
1692 401 set_doorstate_mi(mi, dir);
1693 401 }
1694
1695 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1696 {
1697 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1698 return;
1699 setxdoor_mi(mi, dir, ind, state);
1700 if(auto di = nextscr_mi(mi, dir))
1701 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1702 }
1703
1704 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1705 {
1706 int mi = mapind(cur_map, screen);
1707 set_xdoorstate_mi(mi, dir, ind, state);
1708 }
1709
1710 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1711 // returns: -1 = not a warp screen
1712 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1713 {
1714 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1715
1716
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1717 return -1;
1718
1719 57 int32_t ring=scr->catchall;
1720 57 int32_t size=QMisc.warp[ring].size;
1721
1722
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1723 return -2;
1724
1725 57 int32_t index=-1;
1726
1727
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1728
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1729 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1730 57 index=i;
1731
1732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1733 return -3;
1734
1735 57 index = (index+dw)%size;
1736 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1737 57 }
1738
1739 14767531 void update_combo_cycling()
1740 {
1741 14767531 auto& combo_cache = combo_caches::can_cycle;
1742
1743 static int32_t newdata[176];
1744 static int32_t newcset[176];
1745 static bool initialized=false;
1746
1747 // Just a simple bit of optimization
1748
2/2
✓ Branch 0 taken 14767231 times.
✓ Branch 1 taken 300 times.
14767531 if(!initialized)
1749 {
1750
2/2
✓ Branch 0 taken 52800 times.
✓ Branch 1 taken 300 times.
53100 for(int32_t i=0; i<176; i++)
1751 {
1752 52800 newdata[i]=-1;
1753 52800 newcset[i]=-1;
1754 52800 }
1755
1756 300 initialized=true;
1757 300 }
1758
1759 14767531 std::set<uint16_t> restartanim;
1760
1761
1/2
✓ Branch 0 taken 14767531 times.
✗ Branch 1 not taken.
29924430 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1762 15156899 int screen = scr->screen;
1763 int32_t x;
1764
1765
2/2
✓ Branch 0 taken 2667614224 times.
✓ Branch 1 taken 15156899 times.
2682771123 for(int32_t i=0; i<176; i++)
1766 {
1767 2667614224 x=scr->data[i];
1768 2667614224 auto& mini_cmb = combo_cache.minis[x];
1769
2/2
✓ Branch 0 taken 3273852 times.
✓ Branch 1 taken 2664340372 times.
2667614224 if (!mini_cmb.can_cycle)
1770 2664340372 continue;
1771
1772 3273852 newcombo const& cmb = combobuf[x];
1773
1774 //time to restart
1775
4/4
✓ Branch 0 taken 902678 times.
✓ Branch 1 taken 2371174 times.
✓ Branch 2 taken 474422 times.
✓ Branch 3 taken 428256 times.
3273852 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1776 {
1777 428256 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428256 times.
428256 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1779 428256 newdata[i] = c;
1780
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 428240 times.
428256 if(!(cmb.animflags & AF_CYCLENOCSET))
1781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1782
1783
2/2
✓ Branch 0 taken 427212 times.
✓ Branch 1 taken 1044 times.
428256 if(combobuf[c].animflags & AF_CYCLE)
1784 {
1785 1044 restartanim.insert(c);
1786 1044 }
1787 428256 }
1788 3273852 }
1789
1790 15156899 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1791
2/2
✓ Branch 0 taken 2667614224 times.
✓ Branch 1 taken 15156899 times.
2682771123 for(int32_t i=0; i<176; i++)
1792 {
1793
2/2
✓ Branch 0 taken 428256 times.
✓ Branch 1 taken 2667185968 times.
2667614224 if(newdata[i]==-1)
1794 2667185968 continue;
1795
1796 428256 rpos_t rpos = (rpos_t)(rpos_base + i);
1797 428256 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1798 428256 screen_combo_modify_preroutine(rpos_handle);
1799 428256 scr->data[i]=newdata[i];
1800
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 428240 times.
428256 if(newcset[i]>-1)
1801 428240 scr->cset[i]=newcset[i];
1802 428256 screen_combo_modify_postroutine(rpos_handle);
1803
1804 428256 newdata[i]=-1;
1805 428256 newcset[i]=-1;
1806 428256 }
1807
1808 15156899 word c = scr->numFFC();
1809
2/2
✓ Branch 0 taken 15156899 times.
✓ Branch 1 taken 453626357 times.
468783256 for(word i=0; i<c; i++)
1810 {
1811 453626357 ffcdata& ffc = scr->ffcs[i];
1812 453626357 auto& mini_cmb = combo_cache.minis[ffc.data];
1813
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453622184 times.
453626357 if (!mini_cmb.can_cycle)
1814 453622184 continue;
1815
1816 4173 newcombo const& cmb = combobuf[ffc.data];
1817
1818 //time to restart
1819
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1820 {
1821 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1823 108 zc_ffc_set(ffc, c);
1824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1826
1827
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1828 {
1829 60 restartanim.insert(ffc.data);
1830 60 }
1831 108 }
1832 4173 }
1833
1834
2/2
✓ Branch 0 taken 8417968 times.
✓ Branch 1 taken 6738931 times.
15156899 if(get_qr(qr_CMBCYCLELAYERS))
1835 {
1836
2/2
✓ Branch 0 taken 40433586 times.
✓ Branch 1 taken 6738931 times.
47172517 for(int32_t j=1; j<=6; j++)
1837 {
1838 40433586 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1839
2/2
✓ Branch 0 taken 10859573 times.
✓ Branch 1 taken 29574013 times.
40433586 if (!layer_scr)
1840 29574013 continue;
1841
1842
2/2
✓ Branch 0 taken 1911284848 times.
✓ Branch 1 taken 10859573 times.
1922144421 for(int32_t i=0; i<176; i++)
1843 {
1844 1911284848 x=layer_scr->data[i];
1845 1911284848 auto& mini_cmb = combo_cache.minis[x];
1846
2/2
✓ Branch 0 taken 2228558 times.
✓ Branch 1 taken 1909056290 times.
1911284848 if (!mini_cmb.can_cycle)
1847 1909056290 continue;
1848
1849 2228558 newcombo const& cmb = combobuf[x];
1850
1851 //time to restart
1852
4/4
✓ Branch 0 taken 48215 times.
✓ Branch 1 taken 2180343 times.
✓ Branch 2 taken 37350 times.
✓ Branch 3 taken 10865 times.
2228558 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1853 {
1854 10865 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1855
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10865 times.
10865 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1856 10865 newdata[i] = c;
1857
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10864 times.
10865 if(!(cmb.animflags & AF_CYCLENOCSET))
1858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1859 1 else newcset[i] = layer_scr->cset[i];
1860
1861
2/2
✓ Branch 0 taken 890 times.
✓ Branch 1 taken 9975 times.
10865 if(combobuf[c].animflags & AF_CYCLE)
1862 {
1863 9975 restartanim.insert(c);
1864 9975 }
1865 10865 }
1866 2228558 }
1867
1868
2/2
✓ Branch 0 taken 1911284848 times.
✓ Branch 1 taken 10859573 times.
1922144421 for (int32_t i=0; i<176; i++)
1869 {
1870
2/2
✓ Branch 0 taken 1911273983 times.
✓ Branch 1 taken 10865 times.
1911284848 if(newdata[i]!=-1)
1871 {
1872 10865 layer_scr->data[i]=newdata[i];
1873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10865 times.
10865 if(newcset[i]>-1)
1874 10865 layer_scr->cset[i]=newcset[i];
1875 10865 newdata[i]=-1;
1876 10865 newcset[i]=-1;
1877 10865 }
1878 1911284848 }
1879 10859573 }
1880 6738931 }
1881 15156899 });
1882
1883
2/2
✓ Branch 0 taken 14767531 times.
✓ Branch 1 taken 2657 times.
14770188 for (auto i : restartanim)
1884 {
1885 2657 combobuf[i].tile = combobuf[i].o_tile;
1886 2657 combobuf[i].cur_frame=0;
1887 2657 combobuf[i].aclk = 0;
1888
1/2
✓ Branch 0 taken 2657 times.
✗ Branch 1 not taken.
2657 combo_caches::drawing.refresh(i);
1889 }
1890 14767531 }
1891
1892 1204867082 bool iswater_type(int32_t type)
1893 {
1894 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1895 1204867082 return (combo_class_buf[type].water!=0);
1896 }
1897
1898 bool iswater(int32_t combo)
1899 {
1900 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1901 }
1902 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1903 {
1904 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1905 }
1906
1907 // (x, y) are world coordinates
1908 58608379 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero)
1909 {
1910
8/8
✓ Branch 0 taken 58562240 times.
✓ Branch 1 taken 46139 times.
✓ Branch 2 taken 58521923 times.
✓ Branch 3 taken 40317 times.
✓ Branch 4 taken 58455191 times.
✓ Branch 5 taken 66732 times.
✓ Branch 6 taken 59553 times.
✓ Branch 7 taken 58395638 times.
58608379 if (x<0 || x>=world_w || y<0 || y>=world_h)
1911 212741 return false;
1912
1913 58395638 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero);
1914 58608379 }
1915
1916 96647549 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero)
1917 {
1918 DCHECK_LAYER_NEG1_INDEX(layer);
1919 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1920 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1921
1922 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
1923
2/2
✓ Branch 0 taken 56812878 times.
✓ Branch 1 taken 39834671 times.
96647549 if (get_qr(qr_SMARTER_WATER))
1924 {
1925
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 56812878 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
56812878 if (DRIEDLAKE) return 0;
1926
5/6
✓ Branch 0 taken 19424390 times.
✓ Branch 1 taken 37388488 times.
✓ Branch 2 taken 6518553 times.
✓ Branch 3 taken 12905837 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518553 times.
56812878 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
1927 {
1928
2/2
✓ Branch 0 taken 37370967 times.
✓ Branch 1 taken 12232565 times.
49603532 for (int32_t m = layer; m <= 1; m++)
1929 {
1930
5/6
✓ Branch 0 taken 24465130 times.
✓ Branch 1 taken 12905837 times.
✓ Branch 2 taken 12232565 times.
✓ Branch 3 taken 12232565 times.
✓ Branch 4 taken 12232565 times.
✗ Branch 5 not taken.
49603532 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
1931
1/2
✓ Branch 0 taken 12232565 times.
✗ Branch 1 not taken.
24465130 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
1932 {
1933 37370967 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
1934
2/2
✓ Branch 0 taken 36697695 times.
✓ Branch 1 taken 673272 times.
37370967 if (checkwater > 0)
1935 {
1936 673272 return checkwater;
1937 }
1938 36697695 }
1939 36697695 }
1940 12232565 return 0;
1941 }
1942 else
1943 {
1944
2/2
✓ Branch 0 taken 43921714 times.
✓ Branch 1 taken 41761943 times.
85683657 for(int32_t i=(fullcheck?3:0); i>=0; i--)
1945 {
1946 43921714 int32_t tx2=((i&2)<<2)+x;
1947 43921714 int32_t ty2=((i&1)<<3)+y;
1948 43921714 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
1949 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
1950
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 43900041 times.
43921714 if (!fullcheck)
1951 {
1952 43900041 tx2 = x;
1953 43900041 ty2 = y;
1954
2/2
✓ Branch 0 taken 24646832 times.
✓ Branch 1 taken 19253209 times.
43900041 if(tx2&8) b+=2;
1955
2/2
✓ Branch 0 taken 20345121 times.
✓ Branch 1 taken 23554920 times.
43900041 if(ty2&8) b+=1;
1956 43900041 }
1957
2/2
✓ Branch 0 taken 93971005 times.
✓ Branch 1 taken 43106467 times.
137077472 for (int32_t m = layer; m <= 1; m++)
1958 {
1959 93971005 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
1960
2/2
✓ Branch 0 taken 17735679 times.
✓ Branch 1 taken 76235326 times.
93971005 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1961 {
1962
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735679 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735679 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
1963 {
1964 return 0;
1965 }
1966 17735679 }
1967 else
1968 {
1969
4/4
✓ Branch 0 taken 159084 times.
✓ Branch 1 taken 76076242 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 107932 times.
76235326 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
1970 {
1971 107932 return 0;
1972 }
1973 }
1974
2/2
✓ Branch 0 taken 17735679 times.
✓ Branch 1 taken 76127394 times.
93863073 if (get_qr(qr_NO_SOLID_SWIM))
1975 {
1976
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76076242 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 707315 times.
✓ Branch 5 taken 75368927 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 703854 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76127394 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
1977 {
1978 707315 return 0;
1979 }
1980 75420079 }
1981
3/6
✓ Branch 0 taken 320268 times.
✓ Branch 1 taken 92835490 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320268 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93155758 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
1982 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
1983 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
1984 {
1985 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
1986 }
1987 93155758 }
1988
1989 130971580 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
1990
2/2
✓ Branch 0 taken 87337251 times.
✓ Branch 1 taken 527862 times.
87865113 if (ffcIsAt(ffc_handle, tx2, ty2))
1991 {
1992 527862 auto ty = ffc_handle.ctype();
1993
4/6
✓ Branch 0 taken 527862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383637 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527862 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
1994 527862 return true;
1995 }
1996
1997 87337251 return false;
1998 87865113 });
1999
2/2
✓ Branch 0 taken 42578605 times.
✓ Branch 1 taken 527862 times.
43106467 if (found_ffc_not_water) return 0;
2000
2001
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42563932 times.
42578605 if(!i)
2002 {
2003 127577271 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2004
1/2
✓ Branch 0 taken 85013339 times.
✗ Branch 1 not taken.
85013339 if (ffcIsAt(ffc_handle, tx2, ty2))
2005 {
2006 auto ty = ffc_handle.ctype();
2007 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2008 return true;
2009 }
2010
2011 85013339 return false;
2012 85013339 });
2013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42563932 times.
42563932 if (found_ffc_water) return found_ffc_water->data();
2014 42563932 }
2015
2016 42578605 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2017
2/2
✓ Branch 0 taken 42534111 times.
✓ Branch 1 taken 44494 times.
42578605 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2018
7/12
✓ Branch 0 taken 42253573 times.
✓ Branch 1 taken 280538 times.
✓ Branch 2 taken 10721401 times.
✓ Branch 3 taken 31532172 times.
✓ Branch 4 taken 10243217 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10243217 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42534111 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2019 {
2020
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757495 times.
758722 if (i == 0) return checkcombo;
2021 1227 }
2022 41776616 }
2023 41761943 return 0;
2024 }
2025 }
2026 else
2027 {
2028 39834671 int32_t b = 0;
2029
2/2
✓ Branch 0 taken 20621822 times.
✓ Branch 1 taken 19212849 times.
39834671 if(x&8) b+=2;
2030
2/2
✓ Branch 0 taken 15442035 times.
✓ Branch 1 taken 24392636 times.
39834671 if(y&8) b+=1;
2031
1/2
✓ Branch 0 taken 39834671 times.
✗ Branch 1 not taken.
39834671 if (get_qr(qr_NO_SOLID_SWIM))
2032 {
2033 if (combobuf[combo].walk&(1<<b))
2034 {
2035 return 0;
2036 }
2037 }
2038
1/2
✓ Branch 0 taken 39834671 times.
✗ Branch 1 not taken.
39834671 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2039
8/8
✓ Branch 0 taken 38150503 times.
✓ Branch 1 taken 1684168 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982558 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782308 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39834671 return (((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)?combo:0);//These used to return booleans; returning the combo id of the water combo it caught is essential for Emily's proposed water changes.
2040 }
2041 96903209 }
2042
2043 326 bool isdamage_type(int32_t type)
2044 {
2045
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2046 {
2047 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2048 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2049 return true;
2050 }
2051 326 return false;
2052 326 }
2053
2054 2566493674 bool ispitfall_type(int32_t type)
2055 {
2056 2566493674 return combo_class_buf[type].pit != 0;
2057 }
2058
2059 2566493674 bool ispitfall(int32_t combo)
2060 {
2061 2566493674 return ispitfall_type(combobuf[combo].type);
2062 }
2063
2064 277745561 bool ispitfall(int32_t x, int32_t y)
2065 {
2066
2/2
✓ Branch 0 taken 1454897 times.
✓ Branch 1 taken 276290664 times.
277745561 if(int32_t c = MAPFFCOMBO(x,y))
2067 {
2068 1454897 return ispitfall(c) ? true : false;
2069 }
2070 276290664 int32_t c = MAPCOMBOL(2,x,y);
2071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276290664 times.
276290664 if(ispitfall(c)) return true;
2072
2/2
✓ Branch 0 taken 263213577 times.
✓ Branch 1 taken 13077087 times.
276290664 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2073 {
2074
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263213577 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263213577 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2075 263213577 }
2076 else
2077 {
2078
3/4
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 13076747 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 340 times.
13077087 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2079 }
2080 276290324 c = MAPCOMBOL(1,x,y);
2081
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276290300 times.
276290324 if(ispitfall(c)) return true;
2082
2083
2/2
✓ Branch 0 taken 263213577 times.
✓ Branch 1 taken 13076723 times.
276290300 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2084 {
2085
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263213577 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263213577 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2086 263213577 }
2087 else
2088 {
2089
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13063651 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13076723 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2090 }
2091 276281523 c = MAPCOMBO(x,y);
2092
2/2
✓ Branch 0 taken 70742 times.
✓ Branch 1 taken 276210781 times.
276281523 if(ispitfall(c)) return true;
2093 276210781 return false;
2094 277745561 }
2095
2096 584949045 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2097 {
2098
2/2
✓ Branch 0 taken 9280299 times.
✓ Branch 1 taken 575668746 times.
584949045 if(int32_t c = MAPFFCOMBO(x,y))
2099 {
2100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9280299 times.
9280299 return ispitfall(c) ? c : 0;
2101 }
2102 575668746 int32_t c = MAPCOMBOL(2,x,y);
2103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 575668746 times.
575668746 if(ispitfall(c)) return c;
2104
2105
2/2
✓ Branch 0 taken 532517753 times.
✓ Branch 1 taken 43150993 times.
575668746 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2106 {
2107
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532517753 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532517753 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2108 532517753 }
2109 else
2110 {
2111
3/4
✓ Branch 0 taken 3132 times.
✓ Branch 1 taken 43147861 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3132 times.
43150993 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2112 }
2113 575665614 c = MAPCOMBOL(1,x,y);
2114
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 575665336 times.
575665614 if(ispitfall(c)) return c;
2115
2116
2/2
✓ Branch 0 taken 532517753 times.
✓ Branch 1 taken 43147583 times.
575665336 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2117 {
2118
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532517753 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532517753 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2119 532517753 }
2120 else
2121 {
2122
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43003226 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43147583 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2123 }
2124 575561607 c = MAPCOMBO(x,y);
2125
2/2
✓ Branch 0 taken 175967 times.
✓ Branch 1 taken 575385640 times.
575561607 if(ispitfall(c)) return c;
2126 575385640 return 0;
2127 584949045 }
2128 5324955 bool check_icy(newcombo const& cmb, int type)
2129 {
2130
1/2
✓ Branch 0 taken 5324955 times.
✗ Branch 1 not taken.
5324955 if(cmb.type != cICY)
2131 5324955 return false;
2132 switch(type)
2133 {
2134 case ICY_BLOCK:
2135 return cmb.usrflags&cflag1;
2136 case ICY_PLAYER:
2137 return cmb.usrflags&cflag2;
2138 }
2139 return false;
2140 5324955 }
2141 1775532 int get_icy(int x, int y, int type)
2142 {
2143 1775532 int32_t c = MAPCOMBOL(2,x,y);
2144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1775532 times.
1775532 if(check_icy(combobuf[c], type)) return c;
2145
2146 1775532 int screen = get_screen_for_world_xy(x, y);
2147
2148 1775532 mapscr* scr = get_scr_layer_valid(screen, 2);
2149
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1344763 times.
1775532 if (scr)
2150 {
2151
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1344247 times.
1344763 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2152 {
2153
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2154 516 }
2155 else
2156 {
2157
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1344247 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1344247 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2158 }
2159 1344763 }
2160 1775532 c = MAPCOMBOL(1,x,y);
2161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1775532 times.
1775532 if(check_icy(combobuf[c], type)) return c;
2162
2163 1775532 scr = get_scr_layer_valid(screen, 1);
2164
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1701920 times.
1775532 if (scr)
2165 {
2166
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1699986 times.
1701920 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2167 {
2168
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2169 1934 }
2170 else
2171 {
2172
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1698345 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1699986 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2173 }
2174 1700279 }
2175 1773891 c = MAPCOMBO(x,y);
2176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1773891 times.
1773891 if(check_icy(combobuf[c], type)) return c;
2177 1773891 return 0;
2178 1775532 }
2179
2180 13027448 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2181 {
2182
8/8
✓ Branch 0 taken 13020650 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13011784 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13000152 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428460 times.
✓ Branch 7 taken 12571692 times.
13027448 if(x<0 || x>=world_w || y<0 || y>=world_h)
2183 455756 return false;
2184
2185 12571692 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2186
2/4
✓ Branch 0 taken 12571692 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12571692 times.
12571692 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2187 return true;
2188
2189 12571692 change_rpos_handle_layer(rpos_handle, 1);
2190
2/2
✓ Branch 0 taken 7563722 times.
✓ Branch 1 taken 5007970 times.
12571692 if (rpos_handle.scr->is_valid())
2191
2/4
✓ Branch 0 taken 5007970 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5007970 times.
5007970 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2192 return true;
2193
2194 12571692 change_rpos_handle_layer(rpos_handle, 2);
2195
2/2
✓ Branch 0 taken 10875016 times.
✓ Branch 1 taken 1696676 times.
12571692 if (rpos_handle.scr->is_valid())
2196
2/4
✓ Branch 0 taken 1696676 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1696676 times.
1696676 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2197 return true;
2198
2199 12571692 return false;
2200 13027448 }
2201
2202 6576630 bool isSVLadder(int32_t x, int32_t y)
2203 {
2204 6576630 return checkSV(x, y, mfSIDEVIEWLADDER);
2205 }
2206
2207 6450818 bool isSVPlatform(int32_t x, int32_t y)
2208 {
2209 6450818 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2210 }
2211
2212 6450818 bool checkSVLadderPlatform(int32_t x, int32_t y)
2213 {
2214
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6450818 times.
✓ Branch 2 taken 6450818 times.
✗ Branch 3 not taken.
6450818 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2215 }
2216
2217 1637 bool isstepable(int32_t combo) //can use ladder on it
2218 {
2219
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2220
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2221 {
2222 if(combobuf[combo].usrflags&cflag4)
2223 {
2224 int32_t ldrid = current_item_id(itype_ladder);
2225 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2226 }
2227 }
2228 6 return false;
2229 1637 }
2230
2231 32780 bool isHSGrabbable(newcombo const& cmb)
2232 {
2233
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2234 32407 return cmb.genflags & cflag1;
2235 32780 }
2236
2237 954 bool isSwitchHookable(newcombo const& cmb)
2238 {
2239
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2240 822 return cmb.genflags & cflag2;
2241 954 }
2242
2243 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2244 {
2245 61401 rpos_t cpos = rpos_t::None;
2246
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2247 {
2248 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2249
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2250 {
2251 97359 newcombo const& cmb = combobuf[id];
2252
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2253 32767 }
2254 61401 }
2255
2256 125993 ffcdata* ffc = nullptr;
2257
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2258 {
2259 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2260
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2261 {
2262 113 auto& cmb = ffc_handle.combo();
2263
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2264 {
2265 77 ffc = ffc_handle.ffc;
2266 77 return false;
2267 }
2268 36 }
2269 6889 return true;
2270 6896 });
2271 3393 }
2272
2273
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2274
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2275
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2276 }
2277
2278 5195 bool ishookshottable(int32_t bx, int32_t by)
2279 {
2280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2281 return true;
2282
2283
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2284 8 return false;
2285
2286 5187 bool ret = true;
2287
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2288 {
2289 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2290 15561 int32_t t = combobuf[c].type;
2291
2292
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2293
2294
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2295
2296 12274 int32_t b=1;
2297
2298
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2299
2300
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2301
2302
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2303 904 ret = false;
2304 12274 }
2305
2306 1900 return ret;
2307 5195 }
2308
2309 10105 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2310 {
2311
4/4
✓ Branch 0 taken 9526 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9526 times.
✓ Branch 3 taken 579 times.
10105 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2312 {
2313 579 int pos = COMBOPOS(s->stairx,s->stairy);
2314 579 s->data[pos] = s->secretcombo[sSTAIRS];
2315 579 s->cset[pos] = s->secretcset[sSTAIRS];
2316 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2317
2318
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2319 {
2320 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2321 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2322 256 }
2323
2324 579 return true;
2325 }
2326
2327 9526 return false;
2328 10105 }
2329
2330 15796 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2331 {
2332 DCHECK(base_scr->is_valid());
2333
2334 15796 screen_handles_t screen_handles{};
2335 15796 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2336 15796 return screen_handles;
2337 }
2338
2339 56472360 screen_handles_t create_screen_handles(mapscr* base_scr)
2340 {
2341 DCHECK(get_scr(base_scr->screen) == base_scr);
2342 DCHECK(base_scr->is_valid());
2343
2344 56472360 int screen = base_scr->screen;
2345 screen_handles_t screen_handles;
2346 56472360 screen_handles[0] = {base_scr, base_scr, screen, 0};
2347
2/2
✓ Branch 0 taken 338834160 times.
✓ Branch 1 taken 56472360 times.
395306520 for (int i = 1; i <= 6; i++)
2348 338834160 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2349 56472360 return screen_handles;
2350 }
2351
2352 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2353 {
2354 106202 mapscr* scr = screen_handles[0].scr;
2355 106202 bool didit=false;
2356
2357
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2358 {
2359 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2360
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2361
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2362 {
2363 2635 scr->data[i]++;
2364 2635 didit=true;
2365 2635 }
2366 18691226 }
2367
2368
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2369 {
2370
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2371 {
2372 636660 mapscr* layer_scr = screen_handles[j].scr;
2373
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2374
2375
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2376 {
2377 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2379
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2380 {
2381 348 layer_scr->data[i]++;
2382 348 didit=true;
2383 348 }
2384 30455744 }
2385 173044 }
2386 106110 }
2387
2388 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2389
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2390 {
2391 20406 word c = scr->numFFC();
2392
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2393 {
2394 73350 ffcdata* ffc = &scr->ffcs[i];
2395 73350 newcombo const& cmb = combobuf[ffc->data];
2396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2397
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2398 {
2399 zc_ffc_modify(*ffc, 1);
2400 didit=true;
2401 }
2402 73350 }
2403 20406 }
2404
2405 106202 return didit;
2406 }
2407
2408 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2409 {
2410 14 int screen = screen_handles[0].scr->screen;
2411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2412 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2413 }
2414 471118798 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2415 {
2416 471118798 bool didit=false;
2417
2/2
✓ Branch 0 taken 471094305 times.
✓ Branch 1 taken 24493 times.
471118798 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2418
2419 24493 mapscr* s = screen_handles[0].scr;
2420 24493 int screen = s->screen;
2421 24493 bool is_active_screen = is_in_current_region(s);
2422
2423 21171069 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2424
4/4
✓ Branch 0 taken 21134960 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 21133233 times.
✓ Branch 3 taken 1727 times.
21146576 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2425 1727 didit = true;
2426
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 21081222 times.
21144849 else switch (rpos_handle.ctype())
2427 {
2428 case cLOCKBLOCK: case cLOCKBLOCK2:
2429 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2430 case cCHEST: case cCHEST2:
2431 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2432 case cBOSSCHEST: case cBOSSCHEST2:
2433 {
2434 63627 auto& cmb = rpos_handle.combo();
2435
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2436
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2437 {
2438 29 rpos_handle.increment_data();
2439 29 didit=true;
2440 29 }
2441 62059 break;
2442 }
2443 }
2444 21146576 });
2445
2446
4/4
✓ Branch 0 taken 24452 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 14832 times.
✓ Branch 3 taken 9620 times.
24493 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2447 {
2448 14832 word c = s->numFFC();
2449 14832 int screen_index_offset = get_region_screen_offset(screen);
2450
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 14832 times.
51672 for (uint8_t i = 0; i < c; i++)
2451 {
2452 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2453 36840 auto& cmb = ffc_handle.combo();
2454
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2455 16 didit = true;
2456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2457 {
2458 case cLOCKBLOCK: case cLOCKBLOCK2:
2459 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2460 case cCHEST: case cCHEST2:
2461 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2462 case cBOSSCHEST: case cBOSSCHEST2:
2463 {
2464 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2465 if(cmb.attribytes[5] == xflag)
2466 {
2467 zc_ffc_modify(*ffc_handle.ffc, 1);
2468 didit=true;
2469 }
2470 break;
2471 }
2472 }
2473 36840 }
2474 14832 }
2475
2476 24493 return didit;
2477 471118798 }
2478
2479 14670499 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2480 {
2481 14670499 int screen = screen_handles[0].screen;
2482
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14282666 times.
14670499 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2483 14670499 clear_xstatecombos_mi(screen_handles, mi, triggers);
2484 14670499 }
2485
2486 14722462 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2487 {
2488
2/2
✓ Branch 0 taken 471118784 times.
✓ Branch 1 taken 14722462 times.
485841246 for (int q = 0; q < 32; ++q)
2489 {
2490 471118784 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2491 471118784 }
2492 14722462 }
2493
2494 471118784 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2495 {
2496 471118784 int screen = screen_handles[0].screen;
2497
2/2
✓ Branch 0 taken 12412256 times.
✓ Branch 1 taken 458706528 times.
471118784 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2498 471118784 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2499 }
2500 471118784 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2501 {
2502 471118784 bool didit=false;
2503
1/2
✓ Branch 0 taken 471118784 times.
✗ Branch 1 not taken.
471118784 if (!getxdoor_mi(mi, dir, ind)) return false;
2504
2505 mapscr* scr = screen_handles[0].scr;
2506 int screen = scr->screen;
2507 bool is_active_screen = is_in_current_region(scr);
2508
2509 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2510 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2511 didit = true;
2512 else; //future door combo types?
2513 });
2514
2515 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2516 {
2517 word c = scr->numFFC();
2518 int screen_index_offset = get_region_screen_offset(screen);
2519 for (uint8_t i = 0; i < c; i++)
2520 {
2521 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2522 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2523 didit = true;
2524 else; //future door combo types?
2525 }
2526 }
2527
2528 return didit;
2529 471118784 }
2530
2531 14670499 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2532 {
2533 14670499 mapscr* scr = screen_handles[0].scr;
2534
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14282666 times.
14670499 int mi = mapind(cur_map, scr->screen >= 0x80 ? home_screen : scr->screen);
2535 14670499 clear_xdoors_mi(screen_handles, mi, triggers);
2536 14670499 }
2537
2538 14722462 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2539 {
2540
2/2
✓ Branch 0 taken 471118784 times.
✓ Branch 1 taken 14722462 times.
485841246 for (int q = 0; q < 32; ++q)
2541 {
2542 471118784 remove_xdoors(screen_handles, mi, q, triggers);
2543 471118784 }
2544 14722462 }
2545
2546 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2547 {
2548 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2549 }
2550
2551 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2552 {
2553 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2554 }
2555
2556 76553 bool remove_chests(const screen_handles_t& screen_handles)
2557 {
2558 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2559 }
2560
2561 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2562 {
2563 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2564 }
2565
2566 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2567 {
2568 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2569 }
2570
2571 1383999 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2572 {
2573 1383999 int32_t ct=rpos_handle.ctype();
2574
2575
6/6
✓ Branch 0 taken 1383379 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383127 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383019 times.
✓ Branch 5 taken 108 times.
1383999 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2576 1383019 return;
2577
2578 2465 auto [cx, cy] = rpos_handle.xy();
2579
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2580 {
2581 case cL_STATUE:
2582 620 cx += 4;
2583 620 cy += 7;
2584 620 break;
2585
2586 case cR_STATUE:
2587 252 cx -= 8;
2588 252 cy -= 1;
2589 252 break;
2590
2591 case cC_STATUE:
2592 108 break;
2593 }
2594
2595
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2596 {
2597 // Finds the smallest enemy ID
2598
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2599 {
2600 346 guys.del(j);
2601 346 }
2602 1485 }
2603 1383999 }
2604
2605 15 static int32_t findtrigger(int32_t screen)
2606 {
2607 15 int32_t checkflag=0;
2608 15 int32_t ret = 0;
2609
2610 mapscr* screens[7];
2611
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2612 {
2613 105 screens[j] = get_scr_layer_valid(screen, j);
2614 105 }
2615
2616 15 bool sflag = false;
2617
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2618 {
2619
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2620 {
2621 26752 mapscr* scr = screens[layer+1];
2622
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2623
2624
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2625 8272 checkflag = scr->sflag[j];
2626 else
2627 8272 checkflag = combobuf[scr->data[j]].flag;
2628 16544 sflag = !sflag;
2629
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2630
2631
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2632 {
2633 case mfANYFIRE:
2634 case mfSTRONGFIRE:
2635 case mfMAGICFIRE:
2636 case mfDIVINEFIRE:
2637 case mfARROW:
2638 case mfSARROW:
2639 case mfGARROW:
2640 case mfSBOMB:
2641 case mfBOMB:
2642 case mfBRANG:
2643 case mfMBRANG:
2644 case mfFBRANG:
2645 case mfWANDMAGIC:
2646 case mfREFMAGIC:
2647 case mfREFFIREBALL:
2648 case mfSWORD:
2649 case mfWSWORD:
2650 case mfMSWORD:
2651 case mfXSWORD:
2652 case mfSWORDBEAM:
2653 case mfWSWORDBEAM:
2654 case mfMSWORDBEAM:
2655 case mfXSWORDBEAM:
2656 case mfHOOKSHOT:
2657 case mfWAND:
2658 case mfHAMMER:
2659 case mfSTRIKE:
2660 10 ret += 1;
2661 10 break;
2662 }
2663 16544 }
2664 2640 }
2665
2666 15 return ret;
2667 }
2668
2669 11734 static void log_trigger_secret_reason(TriggerSource source)
2670 {
2671
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11295 times.
11734 if (source == TriggerSource::Singular)
2672 {
2673 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2674 439 }
2675 else
2676 {
2677 11295 const char* source_str = "";
2678
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2732 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 49 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11295 switch (source)
2679 {
2680 case TriggerSource::Singular: break;
2681 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2682 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2683 2732 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2684 475 case TriggerSource::Script: source_str = "a script"; break;
2685 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2686 49 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2687 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2688 case TriggerSource::SCC: source_str = "SCC"; break;
2689 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2690 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2691 }
2692 11295 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2693 }
2694 11734 }
2695
2696 // single:
2697 // >-1 : the singular triggering combo
2698 // -1: triggered by some other cause
2699 11526 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2700 {
2701 11526 log_trigger_secret_reason(source);
2702
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11087 times.
11526 if (single < 0)
2703 11087 get_screen_state(scr->screen).triggered_secrets = true;
2704
2705 11526 bool do_replay_comment = true;
2706 11526 bool from_active_screen = true;
2707 11526 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2708
2709 // Respect secret state carryovers for active screens.
2710
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11087 times.
11526 if (single >= 0) return;
2711 11087 int flag = mSECRET;
2712 11087 int cmap = scr->map;
2713 11087 int cscr = scr->screen;
2714 11087 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2715 11087 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2716
2717 11087 std::vector<int32_t> done;
2718
2/2
✓ Branch 0 taken 10900 times.
✓ Branch 1 taken 187 times.
11087 bool looped = (nmap==cmap+1 && nscr==cscr);
2719
2720
6/6
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 11010 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 552 times.
✓ Branch 4 taken 552 times.
✓ Branch 5 taken 11087 times.
11639 while((nmap!=0) && !looped && !(nscr>=128))
2721 {
2722
9/10
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 301 times.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 74 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 70 times.
552 if (nmap - 1 == cur_map && is_in_current_region(nscr) && (scr->nocarry&flag)!=flag && !get_screen_state(nscr).triggered_secrets)
2723 {
2724
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2725
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2726
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2727 4 }
2728
2729 552 cmap=nmap;
2730 552 cscr=nscr;
2731 552 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2732 552 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2733
2734
2/2
✓ Branch 0 taken 1101 times.
✓ Branch 1 taken 552 times.
1653 for(auto it = done.begin(); it != done.end(); it++)
2735 {
2736
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 77 times.
1101 if(*it == ((nmap-1)<<7)+nscr)
2737 77 looped = true;
2738 1101 }
2739
2740
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 done.push_back(((nmap-1)<<7)+nscr);
2741 }
2742 11526 }
2743
2744 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2745 {
2746 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2747 2437 }
2748
2749 17999 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2750 {
2751 17999 mapscr* scr = screen_handles[0].scr;
2752 17999 int screen = scr->screen;
2753
2754 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2755 // slopes in sideview mode (which required loading nearby screens in loadscr).
2756 // TODO(replays): This should just use `screen`.
2757
3/4
✓ Branch 0 taken 17999 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 535 times.
✓ Branch 3 taken 17464 times.
17999 if (replay_is_active() && do_replay_comment)
2758
4/6
✓ Branch 0 taken 11530 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11530 times.
✓ Branch 4 taken 17464 times.
✗ Branch 5 not taken.
17464 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2759
2760
2/2
✓ Branch 0 taken 6469 times.
✓ Branch 1 taken 11530 times.
17999 if (from_active_screen)
2761 {
2762 5440178 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2763 5428648 auto cid = handle.data();
2764 5428648 auto& cmb = handle.combo();
2765
4/4
✓ Branch 0 taken 5426940 times.
✓ Branch 1 taken 229446 times.
✓ Branch 2 taken 1688 times.
✓ Branch 3 taken 182 times.
5658256 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
2766 {
2767 229628 auto& trig = cmb.triggers[idx];
2768
3/4
✓ Branch 0 taken 65534 times.
✓ Branch 1 taken 163912 times.
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
229628 if (trig.triggerflags[2] & combotriggerSECRETSTR)
2769 {
2770 163912 do_trigger_combo(handle, idx, ctrigSECRETS);
2771
2/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 163892 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
163912 if(handle.data() != cid) break;
2772 163892 }
2773 229608 }
2774 5428648 });
2775 11530 }
2776
2777 17999 int32_t ft=0; //Flag trigger?
2778 17999 int32_t msflag=0; // Misc. secret flag
2779
2780
2/2
✓ Branch 0 taken 3167824 times.
✓ Branch 1 taken 17999 times.
3185823 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2781 {
2782
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3090560 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3167824 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2783
2784 // Remember the misc. secret flag; if triggered, use this instead
2785
4/4
✓ Branch 0 taken 114508 times.
✓ Branch 1 taken 2976491 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65046 times.
3090999 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2786 65046 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2787
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2978723 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3025953 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2788 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2789 else
2790 3025722 msflag=0;
2791
2792
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2169743 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3090999 if(!high16only || single>=0)
2793 {
2794 2169815 int32_t newflag = -1;
2795
2796
2/2
✓ Branch 0 taken 4339630 times.
✓ Branch 1 taken 2169815 times.
6509445 for(int32_t iter=0; iter<2; ++iter)
2797 {
2798 4339630 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2799
2800
2/2
✓ Branch 0 taken 2169815 times.
✓ Branch 1 taken 2169815 times.
4339630 if(iter==1) checkflag=scr->sflag[i]; //Placed
2801
2802 4339630 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2803
2/2
✓ Branch 0 taken 4327396 times.
✓ Branch 1 taken 12234 times.
4339630 if (ft != -1) //Change the combos for the secret
2804 {
2805 // Use misc. secret flag instead if one is present
2806
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2807 32 ft=msflag;
2808
2809 12234 rpos_handle_t rpos_handle;
2810
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2811 {
2812 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2813 5867 screen_combo_modify_preroutine(rpos_handle);
2814 5867 }
2815
2816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2817 {
2818 scr->data[i]++;
2819 }
2820 else
2821 {
2822 12234 scr->data[i] = scr->secretcombo[ft];
2823 12234 scr->cset[i] = scr->secretcset[ft];
2824 }
2825 12234 newflag = scr->secretflag[ft];
2826
2827
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2828 5867 screen_combo_modify_postroutine(rpos_handle);
2829 12234 }
2830 4339630 }
2831
2832
2/2
✓ Branch 0 taken 2157587 times.
✓ Branch 1 taken 12228 times.
2169815 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2833
2834
2/2
✓ Branch 0 taken 13018890 times.
✓ Branch 1 taken 2169815 times.
15188705 for(int32_t j=1; j<=6; j++) //Layers
2835 {
2836 13018890 mapscr* layer_scr = screen_handles[j].scr;
2837
2/2
✓ Branch 0 taken 3183685 times.
✓ Branch 1 taken 9835205 times.
13018890 if (!layer_scr) continue;
2838
2839
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3182960 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3183685 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2840
2841 3183685 int32_t newflag2 = -1;
2842
2843 // Remember the misc. secret flag; if triggered, use this instead
2844
4/4
✓ Branch 0 taken 14180 times.
✓ Branch 1 taken 3169505 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9407 times.
3183685 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2845 9407 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2846
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3047347 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3174278 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2847 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2848 else
2849 3173907 msflag=0;
2850
2851
2/2
✓ Branch 0 taken 6367370 times.
✓ Branch 1 taken 3183685 times.
9551055 for(int32_t iter=0; iter<2; ++iter)
2852 {
2853 6367370 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2854
2/2
✓ Branch 0 taken 3183685 times.
✓ Branch 1 taken 3183685 times.
6367370 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2855
2856 6367370 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2857
2/2
✓ Branch 0 taken 6366892 times.
✓ Branch 1 taken 478 times.
6367370 if (ft != -1) //Change the combos for the secret
2858 {
2859 // Use misc. secret flag instead if one is present
2860
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2861 2 ft=msflag;
2862
2863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2864 {
2865 layer_scr->data[i]++;
2866 }
2867 else
2868 {
2869 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
2870 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
2871 }
2872 478 newflag2 = layer_scr->secretflag[ft];
2873 478 int32_t c=layer_scr->data[i];
2874 478 int32_t cs=layer_scr->cset[i];
2875
2876
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
2877 {
2878 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
2879 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
2880 }
2881 478 }
2882 6367370 }
2883
2884
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3183207 times.
3183685 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
2885 3183685 }
2886 2169815 }
2887 3090999 }
2888
2889 17999 word c = scr->numFFC();
2890
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 17999 times.
524902 for(word i=0; i<c; i++) //FFC 'trigger flags'
2891 {
2892
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
2893
2894
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
2895 {
2896 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
2897 {
2898 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
2899 //No placed flags yet
2900
2901 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2902
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
2903 {
2904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
2905 {
2906 zc_ffc_modify(scr->ffcs[i], 1);
2907 }
2908 else
2909 {
2910 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
2911 31 scr->ffcs[i].cset = scr->secretcset[ft];
2912 }
2913 31 }
2914 }
2915 326378 }
2916 492983 }
2917
2918
2/2
✓ Branch 0 taken 15602 times.
✓ Branch 1 taken 2397 times.
17999 if(checktrigger) //Hit all triggers->16-31
2919 {
2920 2397 checktrigger=false;
2921
2922
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
2923 {
2924 9 int32_t tr = findtrigger(screen); //Normal flags
2925
2926
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
2927 {
2928 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
2929 5 goto endhe;
2930 }
2931 4 }
2932 2392 }
2933
2934
2/2
✓ Branch 0 taken 3166944 times.
✓ Branch 1 taken 17994 times.
3184938 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
2935 {
2936 //If it's an enemies->secret screen, only do the high 16 if told to
2937 //That way you can have secret and burn/bomb entrance separately
2938 3166944 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
2939
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 386320 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3081760 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3166944 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
2940 {
2941 3101296 int32_t newflag = -1;
2942
2943
2/2
✓ Branch 0 taken 6202592 times.
✓ Branch 1 taken 3101296 times.
9303888 for(int32_t iter=0; iter<2; ++iter)
2944 {
2945 6202592 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2946
2947
2/2
✓ Branch 0 taken 3101296 times.
✓ Branch 1 taken 3101296 times.
6202592 if(iter==1) checkflag=scr->sflag[i]; //Placed
2948
2949
4/4
✓ Branch 0 taken 161182 times.
✓ Branch 1 taken 6041410 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66329 times.
6202592 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
2950 {
2951 66329 rpos_handle_t rpos_handle;
2952
2/2
✓ Branch 0 taken 9951 times.
✓ Branch 1 taken 56378 times.
66329 if (from_active_screen)
2953 {
2954 56378 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2955 56378 screen_combo_modify_preroutine(rpos_handle);
2956 56378 }
2957
2958 66329 scr->data[i] = scr->secretcombo[checkflag-16+4];
2959 66329 scr->cset[i] = scr->secretcset[checkflag-16+4];
2960 66329 newflag = scr->secretflag[checkflag-16+4];
2961
2962
2/2
✓ Branch 0 taken 9951 times.
✓ Branch 1 taken 56378 times.
66329 if (from_active_screen)
2963 56378 screen_combo_modify_postroutine(rpos_handle);
2964 66329 }
2965 6202592 }
2966
2967
2/2
✓ Branch 0 taken 3034991 times.
✓ Branch 1 taken 66305 times.
3101296 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
2968
2969
2/2
✓ Branch 0 taken 18607776 times.
✓ Branch 1 taken 3101296 times.
21709072 for(int32_t j=1; j<=6; j++) //Layers
2970 {
2971 18607776 mapscr* layer_scr = screen_handles[j].scr;
2972
2/2
✓ Branch 0 taken 4864640 times.
✓ Branch 1 taken 13743136 times.
18607776 if (!layer_scr) continue;
2973
2974 4864640 int32_t newflag2 = -1;
2975
2976
2/2
✓ Branch 0 taken 9729280 times.
✓ Branch 1 taken 4864640 times.
14593920 for(int32_t iter=0; iter<2; ++iter)
2977 {
2978 9729280 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2979
2980
2/2
✓ Branch 0 taken 4864640 times.
✓ Branch 1 taken 4864640 times.
9729280 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2981
2982
4/4
✓ Branch 0 taken 151244 times.
✓ Branch 1 taken 9578036 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19622 times.
9729280 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
2983 {
2984 19622 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
2985 19622 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
2986 19622 newflag2 = layer_scr->secretflag[checkflag-16+4];
2987 19622 }
2988 9729280 }
2989
2990
2/2
✓ Branch 0 taken 4845018 times.
✓ Branch 1 taken 19622 times.
4864640 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
2991 4864640 }
2992 3101296 }
2993 3166944 }
2994
2995
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 17994 times.
524737 for(word i=0; i<c; i++) // FFCs
2996 {
2997
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
2998 {
2999 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3000
3001 //No placed flags yet
3002
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3003 {
3004
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3005 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3006 else
3007 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3008 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3009 12 }
3010 494906 }
3011 524737 }
3012
3013 endhe:
3014
3015
1/2
✓ Branch 0 taken 17999 times.
✗ Branch 1 not taken.
17999 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3016 {
3017 if (from_active_screen)
3018 activated_timed_warp = true;
3019 scr->timedwarptics = 0;
3020 }
3021 17999 }
3022
3023 // x,y are world coordinates.
3024 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3025 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3026 13503640 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3027 {
3028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13503640 times.
13503640 if (!is_in_world_bounds(x, y)) return false;
3029
3030 13503640 bool found_cflag = false;
3031 13503640 bool found_nflag = false;
3032 13503640 bool single16 = false;
3033 13503640 rpos_t rpos = rpos_t::None;
3034
3035
2/2
✓ Branch 0 taken 13501556 times.
✓ Branch 1 taken 94513288 times.
108014844 for (int32_t layer = -1; layer < 6; layer++)
3036 {
3037
2/2
✓ Branch 0 taken 94511204 times.
✓ Branch 1 taken 2084 times.
94513288 if (MAPFLAG2(layer, x, y) == flag)
3038 {
3039 2084 found_nflag = true;
3040 2084 break;
3041 }
3042 94511204 }
3043
3044
2/2
✓ Branch 0 taken 13503336 times.
✓ Branch 1 taken 94524204 times.
108027540 for (int32_t layer = -1; layer < 6; layer++)
3045 {
3046
2/2
✓ Branch 0 taken 94523900 times.
✓ Branch 1 taken 304 times.
94524204 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3047 {
3048 304 found_cflag = true;
3049 304 break;
3050 }
3051 94523900 }
3052
3053
2/2
✓ Branch 0 taken 94525480 times.
✓ Branch 1 taken 13503640 times.
108029120 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3054 {
3055
2/2
✓ Branch 0 taken 94510892 times.
✓ Branch 1 taken 14588 times.
94525480 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3056 {
3057
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3058 {
3059 112 rpos = COMBOPOS_REGION(x, y);
3060 112 }
3061
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3062 {
3063 52 rpos = COMBOPOS_REGION(x, y);
3064 52 single16 = true;
3065 52 }
3066 14588 }
3067
3068
2/2
✓ Branch 0 taken 94523352 times.
✓ Branch 1 taken 2128 times.
94525480 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3069 {
3070
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3071 {
3072 255 rpos = COMBOPOS_REGION(x, y);
3073 255 }
3074
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3075 {
3076 20 rpos = COMBOPOS_REGION(x, y);
3077 20 single16 = true;
3078 20 }
3079 2128 }
3080 94525480 }
3081
3082 13503640 out_rpos = rpos;
3083 13503640 out_single16 = single16;
3084
4/4
✓ Branch 0 taken 13501556 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13501254 times.
✓ Branch 3 taken 302 times.
13503640 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3085 13503640 }
3086
3087 4456182 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3088 {
3089
8/8
✓ Branch 0 taken 4455942 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4454045 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4453525 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4452573 times.
4456182 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3090
3091 4452573 mapscr* scr = NULL;
3092 4452573 int32_t screen = -1;
3093 4452573 rpos_t trigger_rpos = rpos_t::None;
3094 4452573 bool single16 = false;
3095
3096 4452573 std::vector<std::pair<int, int>> coords;
3097
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x, y});
3098
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x + 15, y});
3099
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x, y + 15});
3100
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x + 15, y + 15});
3101 4452573 std::vector<rpos_t> rposes_seen;
3102
2/2
✓ Branch 0 taken 4450176 times.
✓ Branch 1 taken 17805010 times.
84452582 for (auto [x, y] : coords)
3103 {
3104
2/4
✓ Branch 0 taken 17805010 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17805010 times.
✗ Branch 3 not taken.
35610020 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3105
2/2
✓ Branch 0 taken 17592661 times.
✓ Branch 1 taken 212349 times.
17805010 if (rpos == rpos_t::None)
3106 212349 continue;
3107
3108
4/6
✓ Branch 0 taken 17592661 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17592661 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17592650 times.
35185322 if (MAPFFCOMBOFLAG(x, y) == flag)
3109 {
3110
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3111 11 break;
3112 }
3113
3114 17592650 bool seen = false;
3115
2/2
✓ Branch 0 taken 13503640 times.
✓ Branch 1 taken 22120356 times.
35623996 for (rpos_t r : rposes_seen)
3116 {
3117
2/2
✓ Branch 0 taken 18031346 times.
✓ Branch 1 taken 4089010 times.
22120356 if (r == rpos)
3118 {
3119 4089010 seen = true;
3120 4089010 break;
3121 }
3122 }
3123
2/2
✓ Branch 0 taken 13503640 times.
✓ Branch 1 taken 4089010 times.
17592650 if (seen)
3124 4089010 continue;
3125
3126
1/2
✓ Branch 0 taken 13503640 times.
✗ Branch 1 not taken.
13503640 rposes_seen.push_back(rpos);
3127
4/6
✓ Branch 0 taken 13503640 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13503640 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13501254 times.
27007280 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3128 {
3129
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3130 2386 break;
3131 }
3132 }
3133
3134
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4450176 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4452573 if (screen != -1) scr = get_scr(screen);
3135
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4450176 times.
4452573 if (!scr) return false;
3136
3137
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3138 {
3139 1958 checktrigger = true;
3140
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3141 1958 }
3142 else
3143 {
3144 439 checktrigger = true;
3145
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3146 }
3147
3148
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3149
3150
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3151 {
3152
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3153
3154
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3155 {
3156
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3157 3 setflag=false;
3158 3 }
3159
3160 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3161 // which case only the screen state for mSECRET may be set below.
3162
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3163 {
3164 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3165 }
3166 6 }
3167
3168
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3169
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3170
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3171
3172 2397 return true;
3173 4456182 }
3174
3175 14796824 void update_slopes()
3176 {
3177
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14796824 times.
14939180 for (auto& p : slopes)
3178 {
3179 142356 slope_object& s = p.second;
3180 142356 s.updateslope(); //sets old x/y poses
3181 }
3182 14796824 }
3183
3184 14390603 void update_freeform_combos()
3185 {
3186 14390603 ffscript_engine(false);
3187
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14366431 times.
14390603 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3188 {
3189 14366431 int wrap_right = world_w + 32;
3190 14366431 int wrap_bottom = world_h + 32;
3191
3192 485495057 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3193 471128626 mapscr* scr = ffc_handle.scr;
3194 471128626 ffcdata& thisffc = *ffc_handle.ffc;
3195
3196 // Combo 0?
3197
2/2
✓ Branch 0 taken 44992137 times.
✓ Branch 1 taken 426136489 times.
471128626 if(thisffc.data==0)
3198 426136489 return;
3199
3200 // Changer?
3201
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449108 times.
44992137 if(thisffc.flags&ffc_changer)
3202 543029 return;
3203
3204 // Stationary?
3205
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439264 times.
44449108 if(thisffc.flags&ffc_stationary)
3206 9844 return;
3207
3208 // Frozen because Hero's holding up an item?
3209
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44300982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439264 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3210 138282 return;
3211
3212 // Check for changers
3213
2/2
✓ Branch 0 taken 29543718 times.
✓ Branch 1 taken 14757264 times.
44300982 if (thisffc.link==0)
3214 {
3215 442453057 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3216
2/2
✓ Branch 0 taken 14755728 times.
✓ Branch 1 taken 412940065 times.
427695793 if (ffc_handle.id == other_ffc_handle.id)
3217 14755728 return true;
3218
3219 412940065 ffcdata& otherffc = *other_ffc_handle.ffc;
3220 // Combo 0?
3221
2/2
✓ Branch 0 taken 144689563 times.
✓ Branch 1 taken 268250502 times.
412940065 if(otherffc.data==0)
3222 268250502 return true;
3223
3224 // Not a changer?
3225
2/2
✓ Branch 0 taken 140701386 times.
✓ Branch 1 taken 3988177 times.
144689563 if(!(otherffc.flags&ffc_changer))
3226 140701386 return true;
3227
3228 // Ignore this changer?
3229
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3230 845836 return true;
3231
3232
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3233 ( // At exactly the same position,
3234
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3235
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3236 //or imprecision and close enough
3237
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3238 )
3239 && //and...
3240
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3241 {
3242 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3243 3562 return false;
3244 }
3245
3246 2721195 return true;
3247 426679695 });
3248 14757264 }
3249
3250
2/2
✓ Branch 0 taken 29543718 times.
✓ Branch 1 taken 14757264 times.
44300982 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3251
4/4
✓ Branch 0 taken 14757264 times.
✓ Branch 1 taken 29543718 times.
✓ Branch 2 taken 14679974 times.
✓ Branch 3 taken 14863744 times.
44300982 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3252 {
3253
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681135 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863744 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3254 {
3255 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3256 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3257 97278 thisffc.x += linked_ffc->vx;
3258 97278 thisffc.y += linked_ffc->vy;
3259 97278 }
3260 else
3261 {
3262 14766466 thisffc.prev_changer_x = thisffc.x.getZLong();
3263 14766466 thisffc.prev_changer_y = thisffc.y.getZLong();
3264 14766466 thisffc.x += thisffc.vx;
3265 14766466 thisffc.y += thisffc.vy;
3266 14766466 thisffc.vx += thisffc.ax;
3267 14766466 thisffc.vy += thisffc.ay;
3268
3269
3270
2/2
✓ Branch 0 taken 444012 times.
✓ Branch 1 taken 14322454 times.
14766466 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3271 {
3272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3273
3274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3275
3276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3277
3278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3279 14322454 }
3280 }
3281 14863744 }
3282 else
3283 {
3284
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437238 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3285 76129 thisffc.delay--;
3286 }
3287
3288 // Check if the FFC's off the side of the screen
3289
3290 // Left
3291
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930585 times.
14941034 if(thisffc.x<-32)
3292 {
3293
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3294 {
3295 253 thisffc.x = wrap_right+(thisffc.x+32);
3296 253 thisffc.solid_update(false);
3297 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3298 // Re-enable previous changer
3299 253 thisffc.changer_x = -1000;
3300 253 thisffc.changer_y = -1000;
3301 253 }
3302
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3303 {
3304 69 zc_ffc_set(thisffc, 0);
3305 69 thisffc.flags&=~ffc_carryover;
3306 69 }
3307 10449 }
3308 // Right
3309
2/2
✓ Branch 0 taken 14930404 times.
✓ Branch 1 taken 181 times.
14930585 else if(thisffc.x>=wrap_right)
3310 {
3311
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3312 {
3313 128 thisffc.x = thisffc.x-wrap_right-32;
3314 128 thisffc.solid_update(false);
3315 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3316 128 thisffc.changer_x = -1000;
3317 128 thisffc.changer_y = -1000;
3318 128 }
3319 else
3320 {
3321 53 zc_ffc_set(thisffc, 0);
3322 53 thisffc.flags&=~ffc_carryover;
3323 }
3324 181 }
3325
3326 // Top
3327
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915554 times.
14941034 if(thisffc.y<-32)
3328 {
3329
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3330 {
3331 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3332 8 thisffc.solid_update(false);
3333 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3334 8 thisffc.changer_x = -1000;
3335 8 thisffc.changer_y = -1000;
3336 8 }
3337
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3338 {
3339 317 zc_ffc_set(thisffc, 0);
3340 317 thisffc.flags&=~ffc_carryover;
3341 317 }
3342 25480 }
3343 // Bottom
3344
2/2
✓ Branch 0 taken 14914710 times.
✓ Branch 1 taken 844 times.
14915554 else if(thisffc.y>=wrap_bottom)
3345 {
3346
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3347 {
3348 753 thisffc.y = thisffc.y-wrap_bottom-32;
3349 753 thisffc.solid_update(false);
3350 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3351 753 thisffc.changer_x = -1000;
3352 753 thisffc.changer_y = -1000;
3353 753 }
3354 else
3355 {
3356 91 zc_ffc_set(thisffc, 0);
3357 91 thisffc.flags&=~ffc_carryover;
3358 }
3359 844 }
3360 14941034 thisffc.solid_update();
3361 441768678 });
3362 14366431 }
3363 14390603 }
3364
3365 2098420 bool hitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3366 {
3367
2/2
✓ Branch 0 taken 14685796 times.
✓ Branch 1 taken 2097896 times.
16783692 for(int q = 0; q < 7; ++q)
3368 {
3369
2/2
✓ Branch 0 taken 12587376 times.
✓ Branch 1 taken 2098420 times.
14685796 if(layers&(1<<q)) //if layer is to be checked
3370
2/2
✓ Branch 0 taken 2097896 times.
✓ Branch 1 taken 524 times.
2098420 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3371 524 return true;
3372 14685272 }
3373 2097896 return false;
3374 2098420 }
3375
3376 419684 int gethitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3377 {
3378
2/2
✓ Branch 0 taken 2937788 times.
✓ Branch 1 taken 419684 times.
3357472 for(int q = 0; q < 7; ++q)
3379 {
3380
2/2
✓ Branch 0 taken 2518104 times.
✓ Branch 1 taken 419684 times.
2937788 if(layers&(1<<q)) //if layer is to be checked
3381
1/2
✓ Branch 0 taken 419684 times.
✗ Branch 1 not taken.
419684 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3382 return MAPCOMBO2(q-1,x,y);
3383 2937788 }
3384 419684 return -1;
3385 419684 }
3386
3387 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3388 {
3389 for(int q = 0; q < 7; ++q)
3390 {
3391 if(layers&(1<<q)) //if layer is to be checked
3392 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3393 return true;
3394 }
3395 return false;
3396 }
3397
3398 231 optional<int> nextscr(int screen, int dir)
3399 {
3400 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3402 462 return (m<<7) + s;
3403 231 }
3404
3405 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3406 {
3407 1058 int32_t map = cur_map;
3408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3409 1058 return nextscr2(map, screen, dir);
3410 }
3411
3412 5570 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3413 {
3414 5570 screen = screen_index_direction(screen, (direction)dir);
3415
3416 // need to check for screens on other maps, 's' not valid, etc.
3417 5570 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3418
3419 // Fun fact: when a scrolling warp is triggered, this function
3420 // is never even called! - Saf
3421
2/2
✓ Branch 0 taken 3322 times.
✓ Branch 1 taken 2248 times.
6114 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3422 {
3423
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 545 times.
✓ Branch 4 taken 696 times.
2248 switch(dir)
3424 {
3425 case up:
3426
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3427
3428 83 break;
3429
3430 case down:
3431
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3432
3433 79 break;
3434
3435 case left:
3436
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 336 times.
545 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3437
3438 209 break;
3439
3440 case right:
3441
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 523 times.
696 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3442
3443 173 break;
3444 }
3445
3446 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3447 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3448 544 }
3449
3450 nowarp:
3451
4/4
✓ Branch 0 taken 5506 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5394 times.
5570 if(screen<0||screen>=128)
3452 176 return {-1, -1};
3453
3454 5394 return {map, screen};
3455 5570 }
3456
3457 401 optional<int> nextscr_mi(int mi, int dir)
3458 {
3459 401 int map = mi/MAPSCRSNORMAL;
3460 401 int screen = mi%MAPSCRSNORMAL;
3461 401 auto [m, s] = nextscr2(map, screen, dir);
3462
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if (m == -1) return nullopt;
3463 800 return (m<<7) + s;
3464 401 }
3465
3466 2110 void bombdoor(int32_t x,int32_t y)
3467 {
3468
2/2
✓ Branch 0 taken 2090 times.
✓ Branch 1 taken 20 times.
2110 if (!is_in_world_bounds(x, y))
3469 20 return;
3470
3471 2090 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3472 2090 mapscr* scr = rpos_handle.scr;
3473 2090 int screen = scr->screen;
3474 2898 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3475 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3476
3477
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2011 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2090 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3478 {
3479 69 scr->door[0]=dBOMBED;
3480 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3481 69 setmapflag(scr, mDOOR_UP);
3482 69 markBmap(-1, screen);
3483
3484
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3485 {
3486 69 setmapflag_mi(*v, mDOOR_DOWN);
3487 69 markBmap(-1,*v-(get_currdmap()<<7));
3488 69 }
3489 69 }
3490
3491
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2041 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2090 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3492 {
3493 39 scr->door[1]=dBOMBED;
3494 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3495 39 setmapflag(scr, mDOOR_DOWN);
3496 39 markBmap(-1, rpos_handle.screen);
3497
3498
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3499 {
3500 39 setmapflag_mi(*v, mDOOR_UP);
3501 39 markBmap(-1,*v-(get_currdmap()<<7));
3502 39 }
3503 39 }
3504
3505
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2023 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2090 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3506 {
3507 51 scr->door[2]=dBOMBED;
3508 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3509 51 setmapflag(scr, mDOOR_LEFT);
3510 51 markBmap(-1, rpos_handle.screen);
3511
3512
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3513 {
3514 51 setmapflag_mi(*v, mDOOR_RIGHT);
3515 51 markBmap(-1,*v-(get_currdmap()<<7));
3516 51 }
3517 51 }
3518
3519
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2004 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2090 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3520 {
3521 72 scr->door[3]=dBOMBED;
3522 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3523 72 setmapflag(scr, mDOOR_RIGHT);
3524 72 markBmap(-1, rpos_handle.screen);
3525
3526
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3527 {
3528 72 setmapflag_mi(*v, mDOOR_LEFT);
3529 72 markBmap(-1,*v-(get_currdmap()<<7));
3530 72 }
3531 72 }
3532 2110 }
3533
3534 6375200919 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3535 bool over, bool transp)
3536 {
3537
2/2
✓ Branch 0 taken 3302815909 times.
✓ Branch 1 taken 3072385010 times.
6375200919 if(over)
3538 {
3539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3302815909 times.
3302815909 if(combobuf[cid].animflags & AF_TRANSPARENT)
3540 transp = !transp;
3541
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2983667497 times.
3302815909 if(transp)
3542 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3543 2983667497 else overcombo(dest, x, y, cid, cset);
3544 3302815909 }
3545 3072385010 else putcombo(dest, x, y, cid, cset);
3546 6375200919 }
3547 6375209367 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3548 int32_t cset, byte layer, bool over, bool transp)
3549 {
3550
2/2
✓ Branch 0 taken 750098459 times.
✓ Branch 1 taken 5625110908 times.
6375209367 if (rpos != rpos_t::None)
3551 {
3552 5625110908 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3553
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5624361384 times.
5625110908 if (plrpos != rpos_t::None)
3554 {
3555 5624361384 bool dosw = false;
3556
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5624308524 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5624361384 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3557 {
3558
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3559 {
3560 draw_cmb(dest, x, y,
3561 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3562 }
3563 8448 dosw = true;
3564 8448 }
3565
4/4
✓ Branch 0 taken 31925697 times.
✓ Branch 1 taken 5592427239 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31917249 times.
5624352936 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3566 {
3567 8448 dosw = true;
3568 8448 }
3569
2/2
✓ Branch 0 taken 5624344488 times.
✓ Branch 1 taken 16896 times.
5624361384 if (dosw)
3570 {
3571
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3572 {
3573 default: case swPOOF:
3574 break; //Nothing special here
3575 case swFLICKER:
3576 {
3577
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3578 8448 break; //Drawn this frame
3579 8448 return; //Not drawn this frame
3580 }
3581 case swRISE:
3582 {
3583 //Draw rising up
3584 y -= 8-(abs(Hero.switchhookclk-32)/4);
3585 break;
3586 }
3587 }
3588 8448 }
3589 5624352936 }
3590 5625102460 }
3591
3592 6375200919 draw_cmb(dest, x, y, cid, cset, over, transp);
3593 6375209367 }
3594
3595 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3596 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3597 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3598 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3599 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3600 //
3601 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3602 //
3603 // -16 < comboPositionX*16 + x < bitmapWidth
3604 // -16 < comboPositionY*16 + y < bitmapHeight
3605 //
3606 // The following start/end values are derived directly from the above.
3607 //
3608 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3609 39427398 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3610 {
3611 // if (bmp->clip)
3612 // {
3613 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3614 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3615 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3616 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3617 // return;
3618 // }
3619
3620
2/2
✓ Branch 0 taken 2167250 times.
✓ Branch 1 taken 37260148 times.
39427398 start_x = MAX(0, ceil((-15 - x) / 16.0));
3621
2/2
✓ Branch 0 taken 2176433 times.
✓ Branch 1 taken 37250965 times.
39427398 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3622
2/2
✓ Branch 0 taken 38038824 times.
✓ Branch 1 taken 1388574 times.
39427398 start_y = MAX(0, ceil((-15 - y) / 16.0));
3623
2/2
✓ Branch 0 taken 1677524 times.
✓ Branch 1 taken 37749874 times.
39427398 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3624 39427398 }
3625
3626 186798379 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3627 {
3628
1/2
✓ Branch 0 taken 186798379 times.
✗ Branch 1 not taken.
186798379 if(!show_ffcs) return;
3629 186798379 mapscr* scr = screen_handle.scr;
3630 186798379 mapscr* base_scr = screen_handle.base_scr;
3631
3632 186798379 y += playing_field_offset;
3633
3634 186798379 bool is_bg_layer = layer < -1;
3635
2/2
✓ Branch 0 taken 33897093 times.
✓ Branch 1 taken 152901286 times.
186798379 int real_layer = is_bg_layer ? abs(layer) : layer;
3636
2/2
✓ Branch 0 taken 186798379 times.
✓ Branch 1 taken 5581006546 times.
5767804925 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3637 {
3638
2/2
✓ Branch 0 taken 5375509246 times.
✓ Branch 1 taken 205497300 times.
5581006546 if (base_scr->ffcs[i].data == 0)
3639 5375509246 continue;
3640
4/4
✓ Branch 0 taken 37360890 times.
✓ Branch 1 taken 168136410 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 18677964 times.
205497300 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3641 18677964 continue;
3642
4/4
✓ Branch 0 taken 37360890 times.
✓ Branch 1 taken 149458446 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 18677964 times.
186819336 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3643 18677964 continue;
3644
4/4
✓ Branch 0 taken 149463408 times.
✓ Branch 1 taken 18677964 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 130780482 times.
168141372 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3645 130780482 continue;
3646
3647
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351920 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360890 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3648 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3649
3650 37358406 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3651 37358406 }
3652 186798379 }
3653 170792391 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3654 {
3655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170792391 times.
170792391 if(!show_ffcs) return;
3656 346163004 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3657 175370613 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3658 175370613 do_ffc_layer(bmp, layer, handle, 0, 0);
3659 175370613 });
3660 170792391 }
3661 74977987 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3662 {
3663 74977987 mapscr* scr = screen_handle.scr;
3664 74977987 mapscr* base_scr = screen_handle.base_scr;
3665
3666
4/4
✓ Branch 0 taken 60869135 times.
✓ Branch 1 taken 14108852 times.
✓ Branch 2 taken 14108852 times.
✓ Branch 3 taken 74977987 times.
74977987 if (type == -3 || type == -4)
3667 {
3668 28217704 y += playing_field_offset;
3669
3670
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
28217704 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3671 {
3672 if (base_scr->ffcs[i].data == 0)
3673 continue;
3674
3675 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3676 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3677
3678 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3679 }
3680 return;
3681 }
3682
3683 74977987 x -= viewport.x;
3684 74977987 y -= viewport.y - playing_field_offset;
3685
3686 74977987 bool over = true, transp = false;
3687 74977987 int layer = screen_handle.layer;
3688
3689
7/8
✓ Branch 0 taken 54551896 times.
✓ Branch 1 taken 20426091 times.
✓ Branch 2 taken 13135475 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33627289 times.
✓ Branch 5 taken 20924607 times.
✓ Branch 6 taken 3046783 times.
✓ Branch 7 taken 4243833 times.
74977987 switch(type ? type : layer)
3690 {
3691 case -2: //push blocks
3692
2/2
✓ Branch 0 taken 19518437 times.
✓ Branch 1 taken 14108852 times.
33627289 if (scr)
3693 {
3694
2/2
✓ Branch 0 taken 3435244912 times.
✓ Branch 1 taken 24303777 times.
3434329469 for(int32_t i=0; i<176; i++)
3695 {
3696 3435244912 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3697
3698
10/10
✓ Branch 0 taken 3435074568 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433602596 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3432973613 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420876 times.
✓ Branch 7 taken 3408552737 times.
✓ Branch 8 taken 42763031 times.
✓ Branch 9 taken 16297927 times.
3472292380 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3699
6/8
✓ Branch 0 taken 3430092083 times.
✓ Branch 1 taken 21539346 times.
✓ Branch 2 taken 3430092083 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430092083 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393044615 times.
3432973613 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3700 {
3701
4/4
✓ Branch 0 taken 4772508 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768851 times.
90994552 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3702 5468490 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3703 5468490 }
3704 3414811032 }
3705 24303777 }
3706 38412629 return;
3707
3708 case -1: //over combo
3709
1/2
✓ Branch 0 taken 20924607 times.
✗ Branch 1 not taken.
20924607 if (scr)
3710 {
3711
2/2
✓ Branch 0 taken 3682730832 times.
✓ Branch 1 taken 20924607 times.
3703655439 for(int32_t i=0; i<176; i++)
3712 {
3713
2/2
✓ Branch 0 taken 3663460684 times.
✓ Branch 1 taken 19270148 times.
3682730832 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3714 {
3715
4/4
✓ Branch 0 taken 15517569 times.
✓ Branch 1 taken 3752579 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15495249 times.
19270148 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3716 19270148 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3717 19270148 }
3718 3682730832 }
3719 20924607 }
3720 20924607 return;
3721
3722 case 1:
3723 case 4:
3724 case 5:
3725 case 6:
3726
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13135475 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13135475 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3727 {
3728
1/2
✓ Branch 0 taken 13135475 times.
✗ Branch 1 not taken.
13135475 if (scr)
3729 {
3730
2/2
✓ Branch 0 taken 11476264 times.
✓ Branch 1 taken 1659211 times.
13135475 if(base_scr->layeropacity[layer-1]!=255)
3731 1659211 transp = true;
3732 13135475 break;
3733 }
3734 }
3735 return;
3736
3737 case 2:
3738
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3046783 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3046783 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3739 {
3740
1/2
✓ Branch 0 taken 3046783 times.
✗ Branch 1 not taken.
3046783 if (scr)
3741 {
3742
2/2
✓ Branch 0 taken 2827186 times.
✓ Branch 1 taken 219597 times.
3046783 if(base_scr->layeropacity[layer-1]!=255)
3743 219597 transp = true;
3744
3745
2/2
✓ Branch 0 taken 2917873 times.
✓ Branch 1 taken 128910 times.
3046783 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3746 128910 over = false;
3747
3748 3046783 break;
3749 }
3750 }
3751 return;
3752
3753 case 3:
3754
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4243833 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4243833 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3755 {
3756
1/2
✓ Branch 0 taken 4243833 times.
✗ Branch 1 not taken.
4243833 if (scr)
3757 {
3758
2/2
✓ Branch 0 taken 4170120 times.
✓ Branch 1 taken 73713 times.
4243833 if(base_scr->layeropacity[layer-1]!=255)
3759 73713 transp = true;
3760
3761
2/2
✓ Branch 0 taken 36655 times.
✓ Branch 1 taken 60483 times.
4243833 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3762
2/2
✓ Branch 0 taken 97138 times.
✓ Branch 1 taken 4146695 times.
4243833 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3763 60483 over = false;
3764
3765 4243833 break;
3766 }
3767 }
3768 return;
3769 }
3770
3771 int start_x, end_x, start_y, end_y;
3772 20426091 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3773
2/2
✓ Branch 0 taken 20426091 times.
✓ Branch 1 taken 216559212 times.
236985303 for (int cy = start_y; cy < end_y; cy++)
3774 {
3775
2/2
✓ Branch 0 taken 3277111687 times.
✓ Branch 1 taken 216559212 times.
3493670899 for (int cx = start_x; cx < end_x; cx++)
3776 {
3777 3277111687 int i = cx + cy*16;
3778
4/4
✓ Branch 0 taken 2899406684 times.
✓ Branch 1 taken 377705003 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2889179324 times.
3277111687 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3779 3277111687 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3780 3277111687 }
3781 216559212 }
3782 60869135 }
3783
3784 268788105 bool lenscheck(mapscr* scr, int layer)
3785 {
3786
4/4
✓ Branch 0 taken 268609157 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 268788105 times.
268788105 if(layer < 0 || layer > 6) return true;
3787
2/2
✓ Branch 0 taken 259565871 times.
✓ Branch 1 taken 9222234 times.
268788105 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3788 {
3789
2/2
✓ Branch 0 taken 209692261 times.
✓ Branch 1 taken 49873610 times.
259565871 if(!layer) return true;
3790
8/8
✓ Branch 0 taken 34919337 times.
✓ Branch 1 taken 174772924 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34660367 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34477589 times.
209692261 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3791 489872 return false;
3792 209250513 }
3793 else
3794 {
3795
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9222234 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9222234 times.
9222234 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3796 return false;
3797 }
3798 218472747 return true;
3799 268609157 }
3800
3801 156023072 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3802 {
3803 156023072 bool showlayer = true;
3804 156023072 mapscr* base_scr = screen_handle.base_scr;
3805 156023072 int layer = screen_handle.layer;
3806
2/2
✓ Branch 0 taken 42037754 times.
✓ Branch 1 taken 113985318 times.
156023072 int target = type ? type : layer;
3807
3/4
✓ Branch 0 taken 113985318 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20227475 times.
✓ Branch 3 taken 21810279 times.
156023072 switch(target)
3808 {
3809 case -2:
3810
1/2
✓ Branch 0 taken 20227475 times.
✗ Branch 1 not taken.
20227475 if(!show_layer_push)
3811 showlayer = false;
3812 20227475 break;
3813
3814 case -1:
3815
1/2
✓ Branch 0 taken 21810279 times.
✗ Branch 1 not taken.
21810279 if(!show_layer_over)
3816 showlayer = false;
3817 21810279 break;
3818
3819 case 1: case 2: case 3:
3820 case 4: case 5: case 6:
3821 113985318 showlayer = show_layers[target];
3822 113985318 break;
3823 }
3824
3825
2/2
✓ Branch 0 taken 42037754 times.
✓ Branch 1 taken 113985318 times.
156023072 if(!type)
3826 {
3827
2/2
✓ Branch 0 taken 113849120 times.
✓ Branch 1 taken 136198 times.
113985318 if(!lenscheck(base_scr,layer))
3828 136198 showlayer = false;
3829 113985318 }
3830
3831
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 155886874 times.
156023072 if(showlayer)
3832 {
3833
6/6
✓ Branch 0 taken 60925258 times.
✓ Branch 1 taken 94961616 times.
✓ Branch 2 taken 20482214 times.
✓ Branch 3 taken 40443044 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20426091 times.
155886874 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3834 {
3835 60869135 do_scrolling_layer(bmp, type, screen_handle, x, y);
3836
4/4
✓ Branch 0 taken 20426091 times.
✓ Branch 1 taken 40443044 times.
✓ Branch 2 taken 19233766 times.
✓ Branch 3 taken 1192325 times.
60869135 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3837
2/2
✓ Branch 0 taken 1191749 times.
✓ Branch 1 taken 576 times.
1192901 if(mblock2.draw(bmp,layer))
3838 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3839 60869135 }
3840 155886874 }
3841 156023072 }
3842
3843 102941649 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3844 {
3845 102941649 bool showlayer = true;
3846
3847
2/4
✓ Branch 0 taken 102941649 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 102941649 times.
102941649 if(layer >= 0 && layer <= 6)
3848 {
3849 102941649 showlayer = show_layers[layer];
3850
3851
2/2
✓ Branch 0 taken 102815047 times.
✓ Branch 1 taken 126602 times.
102941649 if(!lenscheck(origin_scr,layer))
3852 126602 showlayer = false;
3853 102941649 }
3854
3855
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102815047 times.
102941649 if (showlayer)
3856 102815047 do_primitives(bmp, layer);
3857 102941649 }
3858
3859 // Called by do_walkflags
3860 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3861 {
3862 newcombo const &c = combobuf[cmbdat];
3863
3864 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3865
3866 int32_t xx = x-xofs;
3867 int32_t yy = y+playing_field_offset-yofs;
3868
3869 int32_t bridgedetected = 0;
3870
3871 for(int32_t i=0; i<4; i++)
3872 {
3873 int32_t tx=((i&2)<<2)+xx - viewport.x;
3874 int32_t ty=((i&1)<<3)+yy - viewport.y;
3875 int32_t tx2=((i&2)<<2)+x - viewport.x;
3876 int32_t ty2=((i&1)<<3)+y - viewport.y;
3877 for (int32_t j = lyr-1; j <= 1; j++)
3878 {
3879 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3880 {
3881 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3882 {
3883 bridgedetected |= (1<<i);
3884 }
3885 }
3886 else
3887 {
3888 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3889 {
3890 bridgedetected |= (1<<i);
3891 }
3892 }
3893 }
3894 if ((bridgedetected & (1<<i)))
3895 {
3896 if (i >= 3) break;
3897 else continue;
3898 }
3899 bool doladdercheck = true;
3900
3901 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
3902 {
3903 for(int32_t k=0; k<8; k+=2)
3904 for(int32_t j=0; j<8; j+=2)
3905 if(((k+j)/2)%2)
3906 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
3907 }
3908 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
3909 {
3910 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
3911 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
3912 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
3913 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
3914 }
3915
3916 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
3917 {
3918 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
3919 {
3920 for(int32_t k=0; k<8; k+=2)
3921 for(int32_t j=0; j<8; j+=2)
3922 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
3923 }
3924 else
3925 {
3926 int32_t color = makecol(178,36,36);
3927
3928 if(isstepable(cmbdat)&& (!doladdercheck))
3929 color=makecol(165,105,8);
3930 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
3931 color=makecol(170,170,170);
3932
3933 rectfill(dest,tx,ty,tx+7,ty+7,color);
3934 }
3935 }
3936 }
3937
3938 // Draw damage combos
3939 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
3940 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
3941 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
3942
3943 if(dmg)
3944 {
3945 int32_t color = makecol(255,255,0);
3946 if (bridgedetected <= 0)
3947 {
3948 for(int32_t k=0; k<16; k+=2)
3949 for(int32_t j=0; j<16; j+=2)
3950 if(((k+j)/2)%2)
3951 {
3952 int32_t x0 = x - viewport.x;
3953 int32_t y0 = y - viewport.y;
3954 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
3955 }
3956 }
3957 else
3958 {
3959 for(int32_t i=0; i<4; i++)
3960 {
3961 if (!(bridgedetected & (1<<i)))
3962 {
3963 int32_t tx=((i&2)<<2)+x - viewport.x;
3964 int32_t ty=((i&1)<<3)+y - viewport.y;
3965 for(int32_t k=0; k<8; k+=2)
3966 for(int32_t j=0; j<8; j+=2)
3967 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
3968 }
3969 }
3970 }
3971 }
3972 }
3973 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
3974 {
3975 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
3976 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
3977 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
3978 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
3979 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
3980 newcombo const &c = combobuf[cmbdat];
3981
3982 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3983
3984 int32_t xx = x-viewport.x;
3985 int32_t yy = y+playing_field_offset-viewport.y;
3986
3987 int32_t bridgedetected = 0;
3988
3989 // Draw damage combos
3990 bool dmg = combo_class_buf[c.type].modify_hp_amount;
3991
3992 for(int32_t i=0; i<4; i++)
3993 {
3994 int32_t tx=((i&2)<<2)+xx;
3995 int32_t ty=((i&1)<<3)+yy;
3996 int32_t tx2=((i&2)<<2)+x;
3997 int32_t ty2=((i&1)<<3)+y;
3998 for (int32_t m = lyr-1; m <= 1; m++)
3999 {
4000 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4001 {
4002 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4003 {
4004 bridgedetected |= (1<<i);
4005 }
4006 }
4007 else
4008 {
4009 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4010 {
4011 bridgedetected |= (1<<i);
4012 }
4013 }
4014 }
4015 if ((bridgedetected & (1<<i)))
4016 continue;
4017 bool doladdercheck = true;
4018
4019 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4020 {
4021 for(int32_t k=0; k<8; k+=2)
4022 for(int32_t j=0; j<8; j+=2)
4023 if(((k+j)/2)%2)
4024 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4025 }
4026 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4027 {
4028 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4029 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4030 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4031 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4032 }
4033
4034 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4035 {
4036 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4037 {
4038 for(int32_t k=0; k<8; k+=2)
4039 for(int32_t j=0; j<8; j+=2)
4040 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4041 }
4042 else
4043 {
4044 ALLEGRO_COLOR* color = &col_solid;
4045
4046 if(isstepable(cmbdat)&& (!doladdercheck))
4047 color=&col_stepable;
4048 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4049 color=&col_lhook;
4050
4051 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4052 }
4053 }
4054
4055 if(dmg)
4056 {
4057 for(int32_t k=0; k<8; k+=2)
4058 for(int32_t j=0; j<8; j+=2)
4059 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4060 }
4061 }
4062 }
4063
4064 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4065 {
4066 newcombo const &c = combobuf[cmbdat];
4067
4068 int32_t xx = x-xofs-viewport.x;
4069 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4070
4071 for(int32_t i=0; i<4; i++)
4072 {
4073 int32_t tx=((i&2)<<2)+xx;
4074 int32_t ty=((i&1)<<3)+yy;
4075
4076 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4077 {
4078 int32_t color = vc(10);
4079
4080 rectfill(dest,tx,ty,tx+7,ty+7,color);
4081 }
4082 }
4083 }
4084 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4085 {
4086 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4087 newcombo const &c = combobuf[cmbdat];
4088
4089 int32_t xx = x-viewport.x;
4090 int32_t yy = y+playing_field_offset-viewport.y;
4091
4092 for(int32_t i=0; i<4; i++)
4093 {
4094 int32_t tx=((i&2)<<2)+xx;
4095 int32_t ty=((i&1)<<3)+yy;
4096
4097 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4098 {
4099 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4100 }
4101 }
4102 }
4103
4104 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4105 {
4106 for(auto cx = 0; cx < 256; cx += 16)
4107 {
4108 for(auto cy = 0; cy < 176; cy += 16)
4109 {
4110 if(isSVLadder(cx,cy))
4111 {
4112 auto nx = cx+x, ny = cy+y;
4113 if(cy && !isSVLadder(cx,cy-16))
4114 line(dest,nx,ny,nx+15,ny,c);
4115 rectfill(dest,nx,ny,nx+3,ny+15,c);
4116 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4117 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4118 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4119 }
4120 else if(isSVPlatform(cx,cy))
4121 {
4122 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4123 }
4124 }
4125 }
4126 }
4127 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4128 {
4129 for(auto cx = 0; cx < 256; cx += 16)
4130 {
4131 for(auto cy = 0; cy < 176; cy += 16)
4132 {
4133 if(isSVLadder(cx,cy))
4134 {
4135 auto nx = cx+x, ny = cy+y;
4136 if(cy && !isSVLadder(cx,cy-16))
4137 al_draw_line(nx,ny,nx+15,ny,c,1);
4138 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4139 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4140 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4141 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4142 }
4143 else if(isSVPlatform(cx,cy))
4144 {
4145 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4146 }
4147 }
4148 }
4149 }
4150
4151 // Walkflags L4 cheat
4152 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4153 {
4154 if (!show_walkflags)
4155 return;
4156
4157 start_info_bmp();
4158
4159 mapscr* scr = screen_handles[0].scr;
4160 for(int32_t i=0; i<176; i++)
4161 {
4162 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4163 }
4164
4165 for(int32_t k=0; k<2; k++)
4166 {
4167 scr = screen_handles[k + 1].scr;
4168
4169 if (scr)
4170 {
4171 for(int32_t i=0; i<176; i++)
4172 {
4173 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4174 }
4175 }
4176 }
4177
4178 end_info_bmp();
4179 }
4180
4181 void do_walkflags(int32_t x, int32_t y)
4182 {
4183 if (!show_walkflags)
4184 return;
4185
4186 x += -viewport.x;
4187 y += playing_field_offset - viewport.y;
4188
4189 start_info_bmp();
4190
4191 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4192 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4193 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4194
4195 end_info_bmp();
4196 }
4197
4198 // Effectflags L4 cheat
4199 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4200 {
4201 if(show_effectflags)
4202 {
4203 start_info_bmp();
4204
4205 for(int32_t i=0; i<176; i++)
4206 {
4207 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4208 }
4209
4210 end_info_bmp();
4211 }
4212 }
4213
4214 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4215 {
4216 272141 int map = scr->map;
4217 272141 int screen = scr->screen;
4218
4219
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4220 {
4221 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4222
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4223
4224
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4225 {
4226 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4227
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4228 {
4229 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4230 604619 }
4231 137432944 }
4232 780869 }
4233 272141 }
4234
4235 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4236 {
4237 272141 word c = scr->numFFC();
4238
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4239 {
4240 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4241
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4242 {
4243 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4244 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4245 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4246 14808 }
4247 537406 }
4248 272141 }
4249
4250 struct nearby_screen_t
4251 {
4252 int screen;
4253 int offx;
4254 int offy;
4255 screen_handles_t screen_handles;
4256 };
4257 typedef std::vector<nearby_screen_t> nearby_screens_t;
4258
4259 15474627 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4260 {
4261 15474627 nearby_screens_t nearby_screens;
4262
4263 15474627 mapscr* base_scr = origin_scr;
4264
1/2
✓ Branch 0 taken 15474627 times.
✗ Branch 1 not taken.
15474627 auto& nearby_screen = nearby_screens.emplace_back();
4265 15474627 nearby_screen.screen = cur_screen;
4266
1/2
✓ Branch 0 taken 15474627 times.
✗ Branch 1 not taken.
15474627 nearby_screen.screen_handles = create_screen_handles(base_scr);
4267
4268 15474627 return nearby_screens;
4269
1/2
✓ Branch 0 taken 15474627 times.
✗ Branch 1 not taken.
15474627 }
4270
4271 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4272 {
4273 48296 nearby_screens_t nearby_screens;
4274
4275
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4276
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4277
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4278
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4279
4280
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4281
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4282
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4283
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4284
4285
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4286 {
4287
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4288 {
4289 169672 int screen = cur_screen + x + y*16;
4290
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4291
4292
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4293
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4294
4295
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4296
4297
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4298 169672 nearby_screen.screen = screen;
4299 169672 nearby_screen.offx = offx;
4300 169672 nearby_screen.offy = offy;
4301
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4302 169672 }
4303 79928 }
4304
4305 48296 return nearby_screens;
4306
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4307
4308 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4309 {
4310 3658 nearby_screens_t nearby_screens;
4311
4312
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4313
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4314
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4315
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4316
4317
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4318
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4319
4320
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4321 {
4322
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4323 {
4324 18600 int screen = -1;
4325 mapscr* base_scr;
4326 int offx, offy;
4327
4328 18600 mapscr* maze_scr = maze_state.scr;
4329 18600 int maze_screen = maze_scr->screen;
4330
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4331
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4332 18600 int maze_screen_dx = x - maze_screen_x;
4333 18600 int maze_screen_dy = y - maze_screen_y;
4334 18600 int exitdir = maze_scr->exitdir;
4335
4336 bool should_draw_maze_screen;
4337
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4338 {
4339 9548 should_draw_maze_screen = true;
4340 9548 }
4341 else
4342 {
4343 9052 should_draw_maze_screen = true;
4344
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4345
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4346
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4347 }
4348
4349
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4350 {
4351 16048 screen = maze_state.scr->screen;
4352 16048 base_scr = maze_state.scr;
4353
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4354 16048 }
4355
4356
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4357 {
4358 2552 screen = cur_screen + x + y*16;
4359
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4360
4361
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4362
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4363
4364
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4365 2552 }
4366
4367
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4368 18600 nearby_screen.screen = screen;
4369 18600 nearby_screen.offx = offx;
4370 18600 nearby_screen.offy = offy;
4371
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4372 18600 }
4373 7308 }
4374
4375 3658 return nearby_screens;
4376
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4377
4378 15526581 static nearby_screens_t get_nearby_screens()
4379 {
4380
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15517367 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15526581 if (maze_state.active && maze_state.loopy)
4381 3658 return get_nearby_screens_smooth_maze();
4382
4383
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15474627 times.
15522923 if (is_in_scrolling_region())
4384 48296 return get_nearby_screens_scrolling_region();
4385
4386 15474627 return get_nearby_screens_non_scrolling_region();
4387 15526581 }
4388
4389 201878713 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4390 {
4391
2/2
✓ Branch 0 taken 203663315 times.
✓ Branch 1 taken 201878713 times.
405542028 for (auto& nearby_screen : nearby_screens)
4392 203663315 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4393 201878713 }
4394
4395 124212648 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4396 {
4397
2/2
✓ Branch 0 taken 15526581 times.
✓ Branch 1 taken 108686067 times.
124212648 if(layer != msgstr_layer) return;
4398
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 if(!dest) dest = framebuf;
4399
4400
2/2
✓ Branch 0 taken 679040 times.
✓ Branch 1 taken 14847541 times.
15526581 if(!(msg_bg_display_buf->clip))
4401 {
4402 679040 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4403 679040 }
4404
4405
2/2
✓ Branch 0 taken 679040 times.
✓ Branch 1 taken 14847541 times.
15526581 if(!(msg_portrait_display_buf->clip))
4406 {
4407 679040 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4408 679040 }
4409
4410
2/2
✓ Branch 0 taken 692447 times.
✓ Branch 1 taken 14834134 times.
15526581 if(!(msg_txt_display_buf->clip))
4411 {
4412 692447 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4413 692447 }
4414 124212648 }
4415
4416 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4417
4418 62106324 static void set_draw_screen_clip(BITMAP* bmp)
4419 {
4420 62106324 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4421 62106324 }
4422
4423 46082339 void draw_screen(bool showhero, bool runGeneric)
4424 {
4425 46082339 clear_info_bmp();
4426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46082339 times.
46082339 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4427 {
4428 FFCore.doScriptMenuDraws();
4429 return;
4430 }
4431
4432
2/2
✓ Branch 0 taken 31156412 times.
✓ Branch 1 taken 14925927 times.
46082339 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4433
4434 46082339 clear_bitmap(framebuf);
4435 46082339 clear_clip_rect(framebuf);
4436
4437 46082339 int32_t cmby2=0;
4438
4439 // Draw some background layers
4440 46082339 clear_bitmap(scrollbuf);
4441
4442 46082339 auto nearby_screens = get_nearby_screens();
4443
4444 // Handle layer 2/3 possibly being background layers.
4445
1/2
✓ Branch 0 taken 46082339 times.
✗ Branch 1 not taken.
61745238 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4446 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4447
2/2
✓ Branch 0 taken 15535617 times.
✓ Branch 1 taken 127282 times.
15662899 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4448 127282 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4449 15662899 });
4450
4451
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 45955057 times.
46082339 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4452 {
4453
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 do_layer_primitives(scrollbuf, 2);
4454
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 particles.draw(scrollbuf, true, 2);
4455 127282 }
4456
2/2
✓ Branch 0 taken 15526581 times.
✓ Branch 1 taken 30555758 times.
46082339 _do_current_ffc_layer(scrollbuf, -2);
4457
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15399299 times.
15526581 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4458
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 draw_msgstr(2, scrollbuf);
4459
4460
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4461 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4462
2/2
✓ Branch 0 taken 15570239 times.
✓ Branch 1 taken 92660 times.
15662899 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4463 92660 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4464 15662899 });
4465
4466
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15433921 times.
15526581 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4467 {
4468
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 do_layer_primitives(scrollbuf, 3);
4469
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 particles.draw(scrollbuf, true, 3);
4470 92660 }
4471
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, -3);
4472
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15433921 times.
15526581 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4473
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 draw_msgstr(3, scrollbuf);
4474
4475 // Draw the main combo screens ("layer 0").
4476
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4477 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4478
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15662899 times.
15662899 if (lenscheck(base_scr, 0))
4479 {
4480 15662899 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4481 15662899 }
4482 15662899 });
4483
4484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if (lenscheck(hero_scr, 0))
4485 {
4486
2/2
✓ Branch 0 taken 454382 times.
✓ Branch 1 taken 15072199 times.
15526581 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4487
3/4
✓ Branch 0 taken 454382 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 450246 times.
458518 if(mblock2.draw(scrollbuf,0))
4488
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4489 15526581 }
4490
4491 // Lens hints, then primitives, then particles.
4492
6/10
✓ Branch 0 taken 15516552 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15516552 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15516552 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15526581 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4493 {
4494
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4495
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4496 5876 }
4497
4498
2/4
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15526581 times.
✗ Branch 3 not taken.
15526581 if(show_layers[0] && lenscheck(hero_scr,0))
4499
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(scrollbuf, 0);
4500
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(scrollbuf, true, 0);
4501
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, 0);
4502
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(0, scrollbuf);
4503
4504
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(scrollbuf);
4505
4506
2/2
✓ Branch 0 taken 15183322 times.
✓ Branch 1 taken 343259 times.
15526581 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4507 {
4508
4/4
✓ Branch 0 taken 15181448 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15093064 times.
30330018 if(showhero &&
4509
4/6
✓ Branch 0 taken 15181448 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15146696 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15146696 times.
✗ Branch 5 not taken.
15181448 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4510 {
4511
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4512 {
4513 34752 cmby2=16;
4514 34752 }
4515
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4516 {
4517 53632 cmby2=-16;
4518 53632 }
4519
4520
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4521
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4522
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4523
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4524
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4525
4526
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4527
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4528
4529
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4530 {
4531
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4532
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4533 15232 }
4534 88384 }
4535 15183322 }
4536
4537
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4538 15662899 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4539 15662899 });
4540
4541
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(scrollbuf, 1);
4542
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(scrollbuf, true, 1);
4543
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, 1);
4544
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(1, scrollbuf);
4545
4546 // Handle layer 2 NOT being used as background layers.
4547
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4548 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4549
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15535617 times.
15662899 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4550 15535617 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4551 15662899 });
4552
4553
2/2
✓ Branch 0 taken 15399299 times.
✓ Branch 1 taken 127282 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4554 {
4555
1/2
✓ Branch 0 taken 15399299 times.
✗ Branch 1 not taken.
15399299 do_layer_primitives(scrollbuf, 2);
4556
1/2
✓ Branch 0 taken 15399299 times.
✗ Branch 1 not taken.
15399299 particles.draw(scrollbuf, true, 2);
4557 15399299 }
4558
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, 2);
4559
2/2
✓ Branch 0 taken 15399299 times.
✓ Branch 1 taken 127282 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4560
1/2
✓ Branch 0 taken 15399299 times.
✗ Branch 1 not taken.
15399299 draw_msgstr(2, scrollbuf);
4561
4562
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4563
4564
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15183322 times.
15526581 if(get_qr(qr_LAYER12UNDERCAVE))
4565 {
4566
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4567
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4568 {
4569 if(Hero.getAction()==climbcovertop)
4570 {
4571 cmby2=16;
4572 }
4573 else if(Hero.getAction()==climbcoverbottom)
4574 {
4575 cmby2=-16;
4576 }
4577
4578 decorations.draw2(scrollbuf,true);
4579 Hero.draw(scrollbuf);
4580 decorations.draw(scrollbuf,true);
4581 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4582 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4583
4584 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4585 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4586
4587 if(int32_t(Hero.getX())&15)
4588 {
4589 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4590 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4591 }
4592 }
4593 343259 }
4594
4595
2/2
✓ Branch 0 taken 454382 times.
✓ Branch 1 taken 15072199 times.
15526581 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4596 {
4597
1/2
✓ Branch 0 taken 15072199 times.
✗ Branch 1 not taken.
30280716 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4598 15208517 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4599
2/2
✓ Branch 0 taken 14478396 times.
✓ Branch 1 taken 730121 times.
15208517 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4600 {
4601 730121 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4602 730121 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4603 730121 }
4604 15208517 });
4605
4606
1/2
✓ Branch 0 taken 15072199 times.
✗ Branch 1 not taken.
15072199 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4607 15072199 }
4608
4609 // Show walkflags cheat
4610
2/4
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15526581 times.
15526581 if (show_walkflags || show_effectflags)
4611 {
4612 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4613 do_walkflags(screen_handles, offx, offy);
4614 do_effectflags(screen_handles[0].base_scr, offx, offy);
4615 });
4616
4617 do_walkflags(0, 0);
4618 }
4619
4620
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4621
4622 // Lens hints, doors etc.
4623
4/8
✓ Branch 0 taken 15516552 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15516552 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15516552 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15526581 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4624 {
4625
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4626 {
4627
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4628
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4629 4153 }
4630
4631
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4632
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4633 10029 }
4634
4635 // Blit those layers onto framebuf
4636
4637
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(framebuf);
4638
4639
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4640
4641 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4642 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4643
4644 // Draw the subscreen, without clipping
4645
2/2
✓ Branch 0 taken 9250859 times.
✓ Branch 1 taken 6275722 times.
15526581 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4646 {
4647 9250859 bool dotime = false;
4648
4/6
✓ Branch 0 taken 9250859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412328 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412328 times.
✗ Branch 5 not taken.
9250859 if (replay_version_check(22)) dotime = game->should_show_time();
4649
1/2
✓ Branch 0 taken 9250859 times.
✗ Branch 1 not taken.
9250859 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4650 9250859 }
4651
4652 // Draw some sprites onto framebuf
4653
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_clip_rect(framebuf,0,0,256,232);
4654
4655
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15427085 times.
15526581 if(!(pricesdisplaybuf->clip))
4656 {
4657
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4658 99496 }
4659
4660
5/6
✓ Branch 0 taken 15480955 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15474627 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15526581 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4661 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4662
4663
8/10
✓ Branch 0 taken 15524707 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15524707 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15489955 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15489955 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15436323 times.
✓ Branch 9 taken 53632 times.
15526581 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4664 {
4665
1/2
✓ Branch 0 taken 15436323 times.
✗ Branch 1 not taken.
15436323 Hero.draw_under(framebuf);
4666
4667
3/4
✓ Branch 0 taken 15436323 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15294938 times.
15436323 if(Hero.isSwimming())
4668 {
4669
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4670
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4671
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4672 141385 }
4673 15436323 }
4674
4675
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15500486 times.
15526581 if(drawguys)
4676 {
4677
4/4
✓ Branch 0 taken 1982149 times.
✓ Branch 1 taken 13518337 times.
✓ Branch 2 taken 990826 times.
✓ Branch 3 taken 991323 times.
15500486 if(get_qr(qr_NOFLICKER) || (frame&1))
4678 {
4679 // Just clips sprites if in a repeating, smooth maze.
4680
2/2
✓ Branch 0 taken 14499949 times.
✓ Branch 1 taken 9214 times.
14509163 bool do_clip = maze_state.active && maze_state.loopy;
4681
4682
3/4
✓ Branch 0 taken 23609261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9100098 times.
✓ Branch 3 taken 14509163 times.
23609261 for(int32_t i=0; i<Ewpns.Count(); i++)
4683 {
4684
3/4
✓ Branch 0 taken 9100098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8902155 times.
9100098 if(((weapon *)Ewpns.spr(i))->behind)
4685
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4686 9100098 }
4687
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4688
4689
3/4
✓ Branch 0 taken 19183147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4673984 times.
✓ Branch 3 taken 14509163 times.
19183147 for(int32_t i=0; i<Lwpns.Count(); i++)
4690 {
4691
3/4
✓ Branch 0 taken 4673984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4670779 times.
4673984 if(((weapon *)Lwpns.spr(i))->behind)
4692
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4693 4673984 }
4694
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4695
4696
6/6
✓ Branch 0 taken 9772562 times.
✓ Branch 1 taken 4736601 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8424262 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14509163 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4697 {
4698
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9094615 times.
9098273 if (do_clip)
4699
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4700 else
4701
1/2
✓ Branch 0 taken 9094615 times.
✗ Branch 1 not taken.
9094615 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4702 9098273 }
4703
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4704
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4705 else
4706
1/2
✓ Branch 0 taken 14505505 times.
✗ Branch 1 not taken.
14505505 guys.draw(framebuf,true);
4707
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4708 {
4709 3658 int maze_screen = maze_state.scr->screen;
4710
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4711
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4712 3658 }
4713
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4714
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4715
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4716
4717
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 chainlinks.draw(framebuf,true);
4718
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4719 //Lwpns.draw(framebuf,true);
4720
4721
3/4
✓ Branch 0 taken 23609261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9100098 times.
✓ Branch 3 taken 14509163 times.
23609261 for(int32_t i=0; i<Ewpns.Count(); i++)
4722 {
4723
3/4
✓ Branch 0 taken 9100098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8902155 times.
✓ Branch 3 taken 197943 times.
9100098 if(!((weapon *)Ewpns.spr(i))->behind)
4724
2/4
✓ Branch 0 taken 8902155 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8902155 times.
✗ Branch 3 not taken.
8902155 Ewpns.spr(i)->draw(framebuf);
4725 9100098 }
4726
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4727
4728
3/4
✓ Branch 0 taken 19183147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4673984 times.
✓ Branch 3 taken 14509163 times.
19183147 for(int32_t i=0; i<Lwpns.Count(); i++)
4729 {
4730
3/4
✓ Branch 0 taken 4673984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4670779 times.
✓ Branch 3 taken 3205 times.
4673984 if(!((weapon *)Lwpns.spr(i))->behind)
4731
2/4
✓ Branch 0 taken 4670779 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4670779 times.
✗ Branch 3 not taken.
4670779 Lwpns.spr(i)->draw(framebuf);
4732 4673984 }
4733
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4734
4735
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4736
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4737 else
4738
1/2
✓ Branch 0 taken 14505505 times.
✗ Branch 1 not taken.
14505505 items.draw(framebuf,true);
4739
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4740 {
4741 3658 int maze_screen = maze_state.scr->screen;
4742
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4743
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4744 3658 }
4745
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4746
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4747
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4748 14509163 }
4749 else
4750 {
4751
3/4
✓ Branch 0 taken 1496695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991323 times.
1496695 for(int32_t i=0; i<Ewpns.Count(); i++)
4752 {
4753
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4754
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4755 505372 }
4756
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4757
4758
3/4
✓ Branch 0 taken 1222321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✓ Branch 3 taken 991323 times.
1222321 for(int32_t i=0; i<Lwpns.Count(); i++)
4759 {
4760
2/4
✓ Branch 0 taken 230998 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 230998 times.
230998 if(((weapon *)Lwpns.spr(i))->behind)
4761 Lwpns.spr(i)->draw(framebuf);
4762 230998 }
4763
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4764
4765
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762703 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991323 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4766 {
4767
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4768 228620 }
4769
4770
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 items.draw(framebuf,false);
4771
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4772
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 chainlinks.draw(framebuf,false);
4773
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4774 //Lwpns.draw(framebuf,false);
4775
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 guys.draw(framebuf,false);
4776
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4777
4778
3/4
✓ Branch 0 taken 1496695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991323 times.
1496695 for(int32_t i=0; i<Ewpns.Count(); i++)
4779 {
4780
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4781 {
4782
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4783 496727 }
4784 505372 }
4785
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4786
4787
3/4
✓ Branch 0 taken 1222321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✓ Branch 3 taken 991323 times.
1222321 for(int32_t i=0; i<Lwpns.Count(); i++)
4788 {
4789
2/4
✓ Branch 0 taken 230998 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✗ Branch 3 not taken.
230998 if(!((weapon *)Lwpns.spr(i))->behind)
4790 {
4791
2/4
✓ Branch 0 taken 230998 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✗ Branch 3 not taken.
230998 Lwpns.spr(i)->draw(framebuf);
4792 230998 }
4793 230998 }
4794
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4795 }
4796
4797
1/2
✓ Branch 0 taken 15500486 times.
✗ Branch 1 not taken.
15500486 guys.draw2(framebuf,true);
4798 15500486 }
4799
4800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if(mirror_portal.destdmap > -1)
4801 mirror_portal.draw(framebuf);
4802
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 portals.draw(framebuf,true);
4803
4804
8/10
✓ Branch 0 taken 15524707 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15524707 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15489955 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15489955 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15436323 times.
✓ Branch 9 taken 53632 times.
15526581 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4805 {
4806
2/2
✓ Branch 0 taken 14988357 times.
✓ Branch 1 taken 447966 times.
15436323 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4807 {
4808
1/2
✓ Branch 0 taken 14988357 times.
✗ Branch 1 not taken.
14988357 mblock2.draw(framebuf,-1);
4809
1/2
✓ Branch 0 taken 14988357 times.
✗ Branch 1 not taken.
14988357 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4810 14988357 }
4811
3/4
✓ Branch 0 taken 15436323 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15294938 times.
✓ Branch 3 taken 141385 times.
15436323 if(!Hero.isSwimming())
4812 {
4813
8/12
✓ Branch 0 taken 15294938 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15294938 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15277194 times.
✓ Branch 5 taken 17744 times.
✓ Branch 6 taken 15277194 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15277194 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15293568 times.
15294938 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4814 {
4815
2/2
✓ Branch 0 taken 17059 times.
✓ Branch 1 taken 15277879 times.
15294938 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4816 17059 }
4817
4818
6/8
✓ Branch 0 taken 15294938 times.
✓ Branch 1 taken 15277879 times.
✓ Branch 2 taken 15294938 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15294938 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15281853 times.
✓ Branch 7 taken 13085 times.
17059 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4819 {
4820
1/2
✓ Branch 0 taken 15281853 times.
✗ Branch 1 not taken.
15281853 decorations.draw2(framebuf,true);
4821
1/2
✓ Branch 0 taken 15281853 times.
✗ Branch 1 not taken.
15281853 Hero.draw(framebuf);
4822
1/2
✓ Branch 0 taken 15281853 times.
✗ Branch 1 not taken.
15281853 decorations.draw(framebuf,true);
4823 15281853 }
4824 15294938 }
4825 15436323 }
4826
4827
3/4
✓ Branch 0 taken 54864043 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39337462 times.
✓ Branch 3 taken 15526581 times.
54864043 for(int32_t i=0; i<guys.Count(); i++)
4828 {
4829
3/4
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15942473 times.
✓ Branch 3 taken 23394989 times.
39337462 if(((enemy*)guys.spr(i))->family == eeWALK)
4830 {
4831
3/4
✓ Branch 0 taken 15942473 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15935178 times.
15942473 if(((eStalfos*)guys.spr(i))->hashero)
4832 {
4833
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4834 7295 }
4835 15942473 }
4836
4837
3/4
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38830300 times.
39337462 if(((enemy*)guys.spr(i))->family == eeWALLM)
4838 {
4839
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4840 {
4841
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4842 1329 }
4843 507162 }
4844
4845
11/20
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39337462 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39337462 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39337462 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39337462 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39337462 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39337462 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39337462 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39337462 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37994768 times.
39337462 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4846 {
4847 //Jumping enemies in front of Hero.
4848
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4849 1342694 }
4850
1/2
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
39337462 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4851 39337462 }
4852
4853 // Draw some layers onto framebuf
4854
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(framebuf);
4855
5/6
✓ Branch 0 taken 15480955 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15474627 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15526581 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4856 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4857
4858 // Handle layer 3 NOT being used as background layers.
4859
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4860 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4861
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15570239 times.
15662899 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4862 15570239 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4863 15662899 });
4864
4865
2/2
✓ Branch 0 taken 15433921 times.
✓ Branch 1 taken 92660 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4866 {
4867
1/2
✓ Branch 0 taken 15433921 times.
✗ Branch 1 not taken.
15433921 do_layer_primitives(framebuf, 3);
4868
1/2
✓ Branch 0 taken 15433921 times.
✗ Branch 1 not taken.
15433921 particles.draw(framebuf, true, 3);
4869 15433921 }
4870
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 3);
4871
2/2
✓ Branch 0 taken 15433921 times.
✓ Branch 1 taken 92660 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4872
1/2
✓ Branch 0 taken 15433921 times.
✗ Branch 1 not taken.
15433921 draw_msgstr(3);
4873
4874
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4875 15662899 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4876 15662899 });
4877
4878
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(framebuf, 4);
4879
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(framebuf, true, 4);
4880
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 4);
4881
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(4);
4882
4883
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4884 15662899 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4885
2/2
✓ Branch 0 taken 14399676 times.
✓ Branch 1 taken 1263223 times.
15662899 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4886 {
4887 1263223 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4888 1263223 do_layer(framebuf, -1, screen_handles[2], offx, offy);
4889 1263223 }
4890 15662899 });
4891
4892
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
4893
4894 // Draw some flying sprites onto framebuf
4895
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 clear_clip_rect(framebuf);
4896
5/6
✓ Branch 0 taken 15480955 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15474627 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15526581 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4897 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4898
4899 //Jumping Hero and jumping enemies are drawn on this layer.
4900
5/8
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15526581 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15526581 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13085 times.
✓ Branch 7 taken 15513496 times.
15526581 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
4901 {
4902
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 decorations.draw2(framebuf,false);
4903
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 Hero.draw(framebuf);
4904
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 chainlinks.draw(framebuf,true);
4905
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4906
4907
3/4
✓ Branch 0 taken 15827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 13085 times.
15827 for(int32_t i=0; i<Lwpns.Count(); i++)
4908 {
4909
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
4910 {
4911
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
4912 239 }
4913 2742 }
4914
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
4915
4916
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 decorations.draw(framebuf,false);
4917 13085 }
4918
4919
5/6
✓ Branch 0 taken 3288982 times.
✓ Branch 1 taken 12237599 times.
✓ Branch 2 taken 44318199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32080600 times.
✓ Branch 5 taken 12237599 times.
47607181 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
4920 {
4921
13/22
✓ Branch 0 taken 32080600 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32080600 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27174502 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27174502 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27174502 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27174502 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27174502 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27174502 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27174502 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27174502 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27167934 times.
32080600 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
4922 {
4923
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
4924 4912666 }
4925 44318199 }
4926 else
4927 {
4928
3/4
✓ Branch 0 taken 10545844 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288982 times.
10545844 for(int32_t i=0; i<guys.Count(); i++)
4929 {
4930
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
4931 {
4932
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
4933 1662516 }
4934 7256862 }
4935 }
4936
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
4937
4938 // Draw the Moving Fairy above layer 3
4939
3/4
✓ Branch 0 taken 18668452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3141871 times.
✓ Branch 3 taken 15526581 times.
18668452 for(int32_t i=0; i<items.Count(); i++)
4940
6/8
✓ Branch 0 taken 3141871 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3072004 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3202024 if(itemsbuf[items.spr(i)->id].family == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
4941
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
4942
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
4943
4944 // Draw some layers onto framebuf
4945
4946
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(framebuf);
4947
4948
2/2
✓ Branch 0 taken 15512229 times.
✓ Branch 1 taken 14352 times.
15526581 if (lightbeam_present)
4949 {
4950 14352 color_map = &trans_table2;
4951
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
4952
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
4953 else
4954
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
4955 14352 color_map = &trans_table;
4956 14352 }
4957
4958
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4959 15662899 do_layer(framebuf, 0, screen_handles[5], offx, offy);
4960 15662899 });
4961
4962
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(framebuf, 5);
4963
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(framebuf, true, 5);
4964
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 5);
4965
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(5);
4966
4967
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
4968
4969
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
4970
4971
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4972 15662899 do_layer(framebuf, 0, screen_handles[6], offx, offy);
4973 15662899 });
4974
4975
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(framebuf, 6);
4976
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(framebuf, true, 6);
4977
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 6);
4978
4979 15526581 bool any_dark = false;
4980
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4981 15662899 mapscr* base_scr = screen_handles[0].scr;
4982 15662899 any_dark |= is_dark(base_scr);
4983 15662899 });
4984
4985 // Handle low drawn darkness
4986
4/4
✓ Branch 0 taken 1256887 times.
✓ Branch 1 taken 14269694 times.
✓ Branch 2 taken 1013116 times.
✓ Branch 3 taken 243771 times.
15526581 if(get_qr(qr_NEW_DARKROOM) && any_dark)
4987 {
4988
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4989 250005 mapscr* base_scr = screen_handles[0].scr;
4990 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
4991 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
4992 250005 });
4993
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
4994
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
4995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4996 250005 mapscr* base_scr = screen_handles[0].scr;
4997
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
4998 {
4999 4730 offy += playing_field_offset;
5000 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5001 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5002 4730 }
5003 250005 });
5004 243771 }
5005
5006 //Darkroom if under the subscreen
5007
6/6
✓ Branch 0 taken 1256887 times.
✓ Branch 1 taken 14269694 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 433603 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15526581 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5008 {
5009
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5010
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5012 {
5013 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5014 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5015 }
5016
5017 231780 color_map = &trans_table2;
5018
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5019 {
5020
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5021
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5022
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5023 144 }
5024 else
5025 {
5026
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5027
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5028 }
5029 231780 color_map = &trans_table;
5030
5031
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5032
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5033 231780 }
5034
5035
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15480955 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15526581 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5036 {
5037 draw_lens_over();
5038 --lensclk;
5039 }
5040
5041 // Draw some text on framebuf
5042
5043
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_clip_rect(framebuf,0,0,256,232);
5044
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5045
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(6);
5046
5047 // Draw the subscreen, without clipping
5048
2/2
✓ Branch 0 taken 6275722 times.
✓ Branch 1 taken 9250859 times.
15526581 if(get_qr(qr_SUBSCREENOVERSPRITES))
5049 {
5050
2/4
✓ Branch 0 taken 6275722 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6275722 times.
✗ Branch 3 not taken.
6275722 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5051
5052 // Draw primitives over subscren
5053
1/2
✓ Branch 0 taken 6275722 times.
✗ Branch 1 not taken.
6275722 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5054 6275722 }
5055
5056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5057 draw_msgstr(6);
5058
5059 // Handle high-drawn darkness
5060
6/6
✓ Branch 0 taken 1256887 times.
✓ Branch 1 taken 14269694 times.
✓ Branch 2 taken 433603 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 421612 times.
15526581 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5061 {
5062
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5063
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5065 {
5066 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5067 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5068 }
5069
5070 11991 color_map = &trans_table2;
5071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5072 {
5073 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5074 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5075 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5076 }
5077 else
5078 {
5079
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5080
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5081 }
5082 11991 color_map = &trans_table;
5083
5084
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5085
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5086 11991 }
5087
5088
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 7);
5089
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(7);
5090
5091
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5092
3/4
✓ Branch 0 taken 14925927 times.
✓ Branch 1 taken 600654 times.
✓ Branch 2 taken 14925927 times.
✗ Branch 3 not taken.
15526581 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5093 76638097 }
5094
5095 // TODO: separate setting door data and drawing door
5096 28152 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5097 {
5098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28152 times.
28152 if (type > 8) return;
5099
5100 28152 int32_t d=scr->door_combo_set;
5101
5102
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12541 times.
28152 switch(type)
5103 {
5104 case dt_wall:
5105 case dt_walk:
5106 if(!even_walls)
5107 break;
5108 [[fallthrough]];
5109 case dt_pass:
5110
3/4
✓ Branch 0 taken 1035 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1035 times.
12541 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5111 1035 break;
5112 [[fallthrough]];
5113 case dt_lock:
5114 case dt_shut:
5115 case dt_boss:
5116 case dt_olck:
5117 case dt_osht:
5118 case dt_obos:
5119 case dt_bomb:
5120
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5121 {
5122 case up:
5123 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5124 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5125 7259 scr->sflag[pos] = 0;
5126 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5127 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5128 7259 scr->sflag[pos+1] = 0;
5129 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5130 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5131 7259 scr->sflag[pos+16] = 0;
5132 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5133 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5134 7259 scr->sflag[pos+16+1] = 0;
5135
5136
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5137 {
5138 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5139 1824 DoorComboSets[d].doorcombo_u[type][0],
5140 1824 DoorComboSets[d].doorcset_u[type][0]);
5141 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5142 1824 DoorComboSets[d].doorcombo_u[type][1],
5143 1824 DoorComboSets[d].doorcset_u[type][1]);
5144 1824 }
5145
5146 7259 break;
5147
5148 case down:
5149 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5150 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5151 6784 scr->sflag[pos] = 0;
5152 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5153 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5154 6784 scr->sflag[pos+1] = 0;
5155 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5156 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5157 6784 scr->sflag[pos+16] = 0;
5158 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5159 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5160 6784 scr->sflag[pos+16+1] = 0;
5161
5162
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5163 {
5164 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5165 1321 DoorComboSets[d].doorcombo_d[type][2],
5166 1321 DoorComboSets[d].doorcset_d[type][2]);
5167 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5168 1321 DoorComboSets[d].doorcombo_d[type][3],
5169 1321 DoorComboSets[d].doorcset_d[type][3]);
5170 1321 }
5171
5172 6784 break;
5173
5174 case left:
5175 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5176 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5177 6362 scr->sflag[pos] = 0;
5178 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5179 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5180 6362 scr->sflag[pos+1] = 0;
5181 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5182 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5183 6362 scr->sflag[pos+16] = 0;
5184 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5185 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5186 6362 scr->sflag[pos+16+1] = 0;
5187 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5188 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5189 6362 scr->sflag[pos+32] = 0;
5190 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5191 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5192 6362 scr->sflag[pos+32+1] = 0;
5193
5194
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5195 {
5196 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5197 1489 DoorComboSets[d].doorcombo_l[type][0],
5198 1489 DoorComboSets[d].doorcset_l[type][0]);
5199 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5200 1489 DoorComboSets[d].doorcombo_l[type][2],
5201 1489 DoorComboSets[d].doorcset_l[type][2]);
5202 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5203 1489 DoorComboSets[d].doorcombo_l[type][4],
5204 1489 DoorComboSets[d].doorcset_l[type][4]);
5205 1489 }
5206
5207 6362 break;
5208
5209 case right:
5210 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5211 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5212 6712 scr->sflag[pos] = 0;
5213 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5214 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5215 6712 scr->sflag[pos+1] = 0;
5216 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5217 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5218 6712 scr->sflag[pos+16] = 0;
5219 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5220 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5221 6712 scr->sflag[pos+16+1] = 0;
5222 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5223 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5224 6712 scr->sflag[pos+32] = 0;
5225 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5226 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5227 6712 scr->sflag[pos+32+1] = 0;
5228
5229
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5230 {
5231 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5232 1654 DoorComboSets[d].doorcombo_r[type][0],
5233 1654 DoorComboSets[d].doorcset_r[type][0]);
5234 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5235 1654 DoorComboSets[d].doorcombo_r[type][2],
5236 1654 DoorComboSets[d].doorcset_r[type][2]);
5237 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5238 1654 DoorComboSets[d].doorcombo_r[type][4],
5239 1654 DoorComboSets[d].doorcset_r[type][4]);
5240 1654 }
5241
5242 6712 break;
5243 }
5244
5245 27117 break;
5246
5247 default:
5248 break;
5249 }
5250 28152 }
5251
5252 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5253 {
5254 706556 int32_t door_combo_set = scr->door_combo_set;
5255 706556 int32_t x = (pos&15)<<4;
5256 706556 int32_t y = (pos&0xF0);
5257 706556 int32_t d = door_combo_set;
5258 706556 x += offx;
5259 706556 y += offy;
5260
5261
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5262 {
5263 case up:
5264 322272 overcombo2(dest,x,y,
5265 161136 DoorComboSets[d].bombdoorcombo_u[0],
5266 161136 DoorComboSets[d].bombdoorcset_u[0]);
5267 322272 overcombo2(dest,x+16,y,
5268 161136 DoorComboSets[d].bombdoorcombo_u[1],
5269 161136 DoorComboSets[d].bombdoorcset_u[1]);
5270 161136 break;
5271
5272 case down:
5273 359286 overcombo2(dest,x,y,
5274 179643 DoorComboSets[d].bombdoorcombo_d[0],
5275 179643 DoorComboSets[d].bombdoorcset_d[0]);
5276 359286 overcombo2(dest,x+16,y,
5277 179643 DoorComboSets[d].bombdoorcombo_d[1],
5278 179643 DoorComboSets[d].bombdoorcset_d[1]);
5279 179643 break;
5280
5281 case left:
5282 392706 overcombo2(dest,x,y,
5283 196353 DoorComboSets[d].bombdoorcombo_l[0],
5284 196353 DoorComboSets[d].bombdoorcset_l[0]);
5285 392706 overcombo2(dest,x,y+16,
5286 196353 DoorComboSets[d].bombdoorcombo_l[1],
5287 196353 DoorComboSets[d].bombdoorcset_l[1]);
5288 392706 overcombo2(dest,x,y+16,
5289 196353 DoorComboSets[d].bombdoorcombo_l[2],
5290 196353 DoorComboSets[d].bombdoorcset_l[2]);
5291 196353 break;
5292
5293 case right:
5294 338848 overcombo2(dest,x,y,
5295 169424 DoorComboSets[d].bombdoorcombo_r[0],
5296 169424 DoorComboSets[d].bombdoorcset_r[0]);
5297 338848 overcombo2(dest,x,y+16,
5298 169424 DoorComboSets[d].bombdoorcombo_r[1],
5299 169424 DoorComboSets[d].bombdoorcset_r[1]);
5300 338848 overcombo2(dest,x,y+16,
5301 169424 DoorComboSets[d].bombdoorcombo_r[2],
5302 169424 DoorComboSets[d].bombdoorcset_r[2]);
5303 169424 break;
5304 }
5305 706556 }
5306
5307 47564 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5308 {
5309
7/8
✓ Branch 0 taken 47456 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47456 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22924 times.
✓ Branch 5 taken 24532 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22394 times.
47564 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5310 25170 return;
5311
5312 int32_t doortype;
5313
5314
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12491 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22394 switch(door)
5315 {
5316 case dWALL:
5317 doortype=dt_wall;
5318 break;
5319
5320 case dWALK:
5321 doortype=dt_walk;
5322 break;
5323
5324 case dOPEN:
5325 12491 doortype=dt_pass;
5326 12491 break;
5327
5328 case dLOCKED:
5329 910 doortype=dt_lock;
5330 910 break;
5331
5332 case dUNLOCKED:
5333 1553 doortype=dt_olck;
5334 1553 break;
5335
5336 case dSHUTTER:
5337
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5338 {
5339 doortype=dt_osht;
5340 get_screen_state(scr->screen).open_doors = -4;
5341 break;
5342 }
5343
5344 [[fallthrough]];
5345 case d1WAYSHUTTER:
5346 3714 doortype=dt_shut;
5347 3714 break;
5348
5349 case dOPENSHUTTER:
5350 1694 doortype=dt_osht;
5351 1694 break;
5352
5353 case dBOSS:
5354 172 doortype=dt_boss;
5355 172 break;
5356
5357 case dOPENBOSS:
5358 67 doortype=dt_obos;
5359 67 break;
5360
5361 case dBOMBED:
5362 1138 doortype=dt_bomb;
5363 1138 break;
5364
5365 default:
5366 655 return;
5367 }
5368
5369
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5110 times.
✓ Branch 4 taken 5230 times.
21739 switch(side)
5370 {
5371 case up:
5372 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5373 5629 break;
5374
5375 case down:
5376 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5377 5770 break;
5378
5379 case left:
5380 5110 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5381 5110 break;
5382
5383 case right:
5384 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5385 5230 break;
5386 }
5387 47564 }
5388
5389 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5390 {
5391 /*
5392 #define dWALL 0 // 000 0
5393 #define dBOMB 6 // 011 0
5394 #define 8 // 100 0
5395 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5396 */
5397
5398
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5399 91 return;
5400
5401 int32_t doortype;
5402
5403
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5404 {
5405 case dWALL:
5406 doortype=dt_wall;
5407 break;
5408
5409 case dWALK:
5410 doortype=dt_walk;
5411 break;
5412
5413 case dOPEN:
5414 50 doortype=dt_pass;
5415 50 break;
5416
5417 case dLOCKED:
5418 doortype=dt_lock;
5419 break;
5420
5421 case dUNLOCKED:
5422 362 doortype=dt_olck;
5423 362 break;
5424
5425 case dSHUTTER:
5426
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5427 {
5428 doortype=dt_osht;
5429 get_screen_state(cur_screen).open_doors = -4;
5430 break;
5431 }
5432
5433 [[fallthrough]];
5434 case d1WAYSHUTTER:
5435 1757 doortype=dt_shut;
5436 1757 break;
5437
5438 case dOPENSHUTTER:
5439 3958 doortype=dt_osht;
5440 3958 break;
5441
5442 case dBOSS:
5443 4 doortype=dt_boss;
5444 4 break;
5445
5446 case dOPENBOSS:
5447 51 doortype=dt_obos;
5448 51 break;
5449
5450 case dBOMBED:
5451 231 doortype=dt_bomb;
5452 231 break;
5453
5454 default:
5455 return;
5456 }
5457
5458
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5459 {
5460 case up:
5461
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5462 {
5463 case dBOMBED:
5464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5465 {
5466 69 over_door(scr,dest,39,side,0,0);
5467 69 }
5468 [[fallthrough]];
5469 default:
5470 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5471 1860 break;
5472 }
5473
5474 1860 break;
5475
5476 case down:
5477
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5478 {
5479 case dBOMBED:
5480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5481 {
5482 39 over_door(scr,dest,135,side,0,0);
5483 39 }
5484 [[fallthrough]];
5485 default:
5486 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5487 1357 break;
5488 }
5489
5490 1357 break;
5491
5492 case left:
5493
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5494 {
5495 case dBOMBED:
5496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5497 {
5498 51 over_door(scr,dest,66,side,0,0);
5499 51 }
5500 [[fallthrough]];
5501 default:
5502 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5503 1514 break;
5504 }
5505
5506 1514 break;
5507
5508 case right:
5509
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5510 {
5511 case dBOMBED:
5512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5513 {
5514 72 over_door(scr,dest,77,side,0,0);
5515 72 }
5516 [[fallthrough]];
5517 default:
5518 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5519 1682 break;
5520 }
5521
5522 1682 break;
5523 }
5524 6504 }
5525
5526 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5527 {
5528
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5529 {
5530 586 putcombo(dest,x, y, combo, cset);
5531 586 }
5532 586 }
5533
5534 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5535 {
5536
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5537 {
5538 219 overcombo(dest,x, y, combo, cset);
5539 219 }
5540 293 }
5541
5542 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5543 {
5544 125 int32_t d = scr->door_combo_set;
5545
5546
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5547 {
5548 case up:
5549 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5550 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5551 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5552 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5553 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5554 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5555 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5556 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5557 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5558 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5559 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5560 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5561 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5562 43 DoorComboSets[d].bombdoorcombo_u[0],
5563 43 DoorComboSets[d].bombdoorcset_u[0]);
5564 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5565 43 DoorComboSets[d].bombdoorcombo_u[1],
5566 43 DoorComboSets[d].bombdoorcset_u[1]);
5567 43 break;
5568
5569 case down:
5570 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5571 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5572 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5573 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5574 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5575 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5576 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5577 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5578 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5579 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5580 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5581 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5582 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5583 39 DoorComboSets[d].bombdoorcombo_d[0],
5584 39 DoorComboSets[d].bombdoorcset_d[0]);
5585 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5586 39 DoorComboSets[d].bombdoorcombo_d[1],
5587 39 DoorComboSets[d].bombdoorcset_d[1]);
5588 39 break;
5589
5590 case left:
5591 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5592 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5593 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5594 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5595 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5596 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5597 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5598 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5599 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5600 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5601 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5602 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5603 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5604 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5605 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5606 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5607 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5608 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5609 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5610 6 DoorComboSets[d].bombdoorcombo_l[0],
5611 6 DoorComboSets[d].bombdoorcset_l[0]);
5612 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5613 6 DoorComboSets[d].bombdoorcombo_l[1],
5614 6 DoorComboSets[d].bombdoorcset_l[1]);
5615 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5616 6 DoorComboSets[d].bombdoorcombo_l[2],
5617 6 DoorComboSets[d].bombdoorcset_l[2]);
5618 6 break;
5619
5620 case right:
5621 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5622 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5623 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5624 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5625 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5626 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5627 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5628 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5629 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5630 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5631 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5632 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5633 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5634 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5635 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5636 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5637 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5638 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5639 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5640 37 DoorComboSets[d].bombdoorcombo_r[0],
5641 37 DoorComboSets[d].bombdoorcset_r[0]);
5642 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5643 37 DoorComboSets[d].bombdoorcombo_r[1],
5644 37 DoorComboSets[d].bombdoorcset_r[1]);
5645 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5646 37 DoorComboSets[d].bombdoorcombo_r[2],
5647 37 DoorComboSets[d].bombdoorcset_r[2]);
5648 37 break;
5649 }
5650 125 }
5651
5652 5346447 void openshutters(mapscr* scr)
5653 {
5654 5346447 bool opened_door = false;
5655
2/2
✓ Branch 0 taken 5346447 times.
✓ Branch 1 taken 21385788 times.
26732235 for(int32_t i=0; i<4; i++)
5656
2/2
✓ Branch 0 taken 21381830 times.
✓ Branch 1 taken 3958 times.
21389746 if(scr->door[i]==dSHUTTER)
5657 {
5658 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5659 3958 scr->door[i]=dOPENSHUTTER;
5660 3958 opened_door = true;
5661 3958 }
5662
5663 5346447 auto& combo_cache = combo_caches::shutter;
5664 2012538143 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5665
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2005581069 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1610624 times.
2007191696 if (!combo_cache.minis[handle.data()].shutter)
5666 2007191693 return;
5667 3 auto cid = handle.data();
5668 3 auto& cmb = handle.combo();
5669
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
5670 {
5671 3 auto& trig = cmb.triggers[idx];
5672
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(trig.triggerflags[0] & combotriggerSHUTTER)
5673 {
5674 3 do_trigger_combo(handle, idx);
5675
1/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(handle.data() != cid) break;
5676 }
5677 }
5678 2007191696 });
5679
5680
2/2
✓ Branch 0 taken 5343716 times.
✓ Branch 1 taken 2731 times.
5346447 if(opened_door)
5681 2731 sfx(WAV_DOOR,128);
5682 5346447 }
5683
5684 15104581 void clear_darkroom_bitmaps()
5685 {
5686 15104581 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5687 15104581 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5688 15104581 }
5689
5690 16017890 bool is_dark(const mapscr* scr)
5691 {
5692 16017890 bool dark = scr->flags&fDARK;
5693
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16014168 times.
16017890 if (region_is_lit) return !dark;
5694 16014168 return dark;
5695 16017890 }
5696
5697 39213 bool scrolling_is_dark(const mapscr* scr)
5698 {
5699 39213 bool dark = scr->flags&fDARK;
5700
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39211 times.
39213 if (scrolling_region_is_lit) return !dark;
5701 39211 return dark;
5702 39213 }
5703
5704 36734 bool is_any_dark()
5705 {
5706 36734 bool dark = false;
5707 74724 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5708 37990 dark |= (bool)(is_dark(scr));
5709 37990 });
5710 36734 return dark;
5711 }
5712
5713 404 static mapscr prev_origin_scrs[7];
5714 404 static std::set<int> loadscr_ffc_script_ids_to_remove;
5715
5716 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5717 {
5718 mapscr* base_scr = screens[0];
5719 mapscr* previous_scr = &prev_origin_scrs[0];
5720
5721 for (int i = 0; i < 176; i++)
5722 {
5723 if (base_scr->data[i] == 0)
5724 {
5725 base_scr->data[i] = previous_scr->data[i];
5726 base_scr->sflag[i] = previous_scr->sflag[i];
5727 base_scr->cset[i] = previous_scr->cset[i];
5728 }
5729 }
5730
5731 for (int i = 0; i < 6; i++)
5732 {
5733 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5734 {
5735 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5736 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5737
5738 for (int j = 0; j < 176; j++)
5739 {
5740 if (TheMaps[lm].data[j] == 0)
5741 {
5742 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5743 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5744 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5745 }
5746 }
5747 }
5748 }
5749
5750 for (int i = 1; i <= 6; i++)
5751 {
5752 mapscr* scr = screens[i];
5753 previous_scr = &prev_origin_scrs[i];
5754
5755 if (scr->layermap[i] > 0)
5756 {
5757 for (int y = 0; y < 11; y++)
5758 {
5759 for (int x = 0; x < 16; x++)
5760 {
5761 int c = y*16+x;
5762
5763 if (scr->data[c]==0)
5764 {
5765 scr->data[c] = previous_scr->data[c];
5766 scr->sflag[c] = previous_scr->sflag[c];
5767 scr->cset[c] = previous_scr->cset[c];
5768 }
5769 }
5770 }
5771 }
5772 }
5773 }
5774
5775 37074 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5776 {
5777 37074 std::vector<mapscr*> screens;
5778
5779
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
37074 const mapscr* source = get_canonical_scr(cur_map, screen);
5780
2/4
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37074 times.
✗ Branch 3 not taken.
37074 mapscr* base_scr = new mapscr(*source);
5781 37074 temporary_screens[screen*7] = base_scr;
5782
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
37074 screens.push_back(base_scr);
5783
5784 37074 base_scr->valid |= mVALID; // layer 0 is always valid
5785
5786
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35830 times.
37074 if (screen == cur_screen)
5787 35830 origin_scr = base_scr;
5788
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35830 times.
37074 if (screen == hero_screen)
5789 35830 hero_scr = prev_hero_scr = base_scr;
5790
5791
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36955 times.
37074 if (source->script > 0)
5792
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5793
5794
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 222444 times.
259518 for (int i = 0; i < 6; i++)
5795 {
5796
2/2
✓ Branch 0 taken 173412 times.
✓ Branch 1 taken 49032 times.
222444 if(source->layermap[i]>0)
5797 {
5798
3/6
✓ Branch 0 taken 49032 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49032 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49032 times.
✗ Branch 5 not taken.
49032 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5799 49032 layer_scr->map = cur_map;
5800 49032 layer_scr->screen = screen;
5801
1/2
✓ Branch 0 taken 49032 times.
✗ Branch 1 not taken.
49032 screens.push_back(layer_scr);
5802 49032 }
5803 else
5804 {
5805
1/2
✓ Branch 0 taken 173412 times.
✗ Branch 1 not taken.
173412 mapscr* layer_scr = new mapscr();
5806 173412 layer_scr->map = cur_map;
5807 173412 layer_scr->screen = screen;
5808
1/2
✓ Branch 0 taken 173412 times.
✗ Branch 1 not taken.
173412 screens.push_back(layer_scr);
5809 }
5810 222444 temporary_screens[screen*7+i+1] = screens[i+1];
5811 222444 }
5812
5813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37074 times.
37074 if (screen_overlay)
5814 handle_screen_overlay(screens);
5815
5816
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36930 times.
37074 if (ffc_overlay)
5817 {
5818 144 mapscr* previous_scr = &prev_origin_scrs[0];
5819
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5820
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5821 {
5822
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5823 {
5824
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5825 274 ffc.screen_spawned = screen;
5826
5827
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5828
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5830 {
5831 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5832 }
5833 274 }
5834 4608 }
5835 144 }
5836
5837
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
1142083 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5838
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
37074 int num_ffcs = base_scr->numFFC();
5839
2/2
✓ Branch 0 taken 1105009 times.
✓ Branch 1 taken 37074 times.
1142083 for (word i = 0; i < num_ffcs; i++)
5840 {
5841 1105009 base_scr->ffcs[i].screen_spawned = screen;
5842
1/2
✓ Branch 0 taken 1105009 times.
✗ Branch 1 not taken.
1105009 base_scr->ffcs[i].x += offx;
5843
1/2
✓ Branch 0 taken 1105009 times.
✗ Branch 1 not taken.
1105009 base_scr->ffcs[i].y += offy;
5844 1105009 }
5845 37074 }
5846
5847 37074 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5848 {
5849 37074 mapscr* base_scr = get_scr(screen);
5850 37074 int mi = mapind(cur_map, screen);
5851
5852 // Apply perm secrets, if applicable.
5853
2/2
✓ Branch 0 taken 11519 times.
✓ Branch 1 taken 25555 times.
37074 if (canPermSecret(dmap, screen))
5854 {
5855
2/2
✓ Branch 0 taken 23031 times.
✓ Branch 1 taken 2524 times.
25555 if(game->maps[mi] & mSECRET) // if special stuff done before
5856 {
5857 2524 reveal_hidden_stairs(base_scr, screen, false);
5858 2524 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5859 2524 }
5860
2/2
✓ Branch 0 taken 25552 times.
✓ Branch 1 taken 3 times.
25555 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5861 {
5862
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5863 {
5864 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5865
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5866 {
5867 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5868
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5869 {
5870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5871 {
5872 3 layer_scr->data[pos] += 1;
5873 3 }
5874 3 }
5875 3696 }
5876 21 }
5877 3 }
5878 25555 }
5879
5880 37074 auto screen_handles = create_screen_handles(base_scr);
5881
5882 37074 int destlvl = DMaps[dmap].level;
5883 37074 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5884 37074 toggle_gswitches_load(screen_handles);
5885
5886 37074 bool should_check_for_state_things = (screen < 0x80);
5887
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36167 times.
37074 if (should_check_for_state_things)
5888 {
5889
2/2
✓ Branch 0 taken 35795 times.
✓ Branch 1 taken 372 times.
36167 if (game->maps[mi]&mLOCKBLOCK)
5890 372 remove_lockblocks(screen_handles);
5891
2/2
✓ Branch 0 taken 36109 times.
✓ Branch 1 taken 58 times.
36167 if (game->maps[mi]&mBOSSLOCKBLOCK)
5892 58 remove_bosslockblocks(screen_handles);
5893
2/2
✓ Branch 0 taken 36011 times.
✓ Branch 1 taken 156 times.
36167 if (game->maps[mi]&mCHEST)
5894 156 remove_chests(screen_handles);
5895
1/2
✓ Branch 0 taken 36167 times.
✗ Branch 1 not taken.
36167 if (game->maps[mi]&mLOCKEDCHEST)
5896 remove_lockedchests(screen_handles);
5897
2/2
✓ Branch 0 taken 36156 times.
✓ Branch 1 taken 11 times.
36167 if (game->maps[mi]&mBOSSCHEST)
5898 11 remove_bosschests(screen_handles);
5899
5900 36167 clear_xdoors_mi(screen_handles, mi, true);
5901 36167 clear_xstatecombos_mi(screen_handles, mi, true);
5902 14714360 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
5903 // This is duplicated 3 places... can this be reduced?
5904 14678193 auto cid = handle.data();
5905 14678193 auto* cmb = &handle.combo();
5906 14678193 bool done = false;
5907 14678193 std::set<int32_t> visited;
5908
4/4
✓ Branch 0 taken 14674176 times.
✓ Branch 1 taken 14674176 times.
✓ Branch 2 taken 4017 times.
✓ Branch 3 taken 4017 times.
29356386 while(!done)
5909 {
5910
4/8
✓ Branch 0 taken 14674176 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14674176 times.
✓ Branch 4 taken 4017 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4017 times.
14678193 if(visited.contains(cid))
5911 {
5912 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
5913 break; // prevent infinite loop
5914 }
5915
2/4
✓ Branch 0 taken 14674176 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4017 times.
✗ Branch 3 not taken.
14678193 visited.insert(cid);
5916
5917 14678193 done = true; // don't loop again unless something changes
5918
4/4
✓ Branch 0 taken 14674176 times.
✓ Branch 1 taken 549385 times.
✓ Branch 2 taken 4017 times.
✓ Branch 3 taken 400 times.
15227978 for(size_t idx = 0; idx < cmb->triggers.size(); ++idx)
5919 {
5920 549785 auto& trig = cmb->triggers[idx];
5921
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 549385 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 400 times.
549785 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
5922 do_trigger_combo(handle, idx);
5923 549785 else continue; // can skip checking handle.data()
5924
5925 if(handle.data() != cid)
5926 {
5927 cid = handle.data();
5928 cmb = &handle.combo();
5929 done = false; // loop again for the new combo
5930 break;
5931 }
5932 }
5933 }
5934 14678193 });
5935 36167 }
5936
5937 // check doors
5938
2/2
✓ Branch 0 taken 25554 times.
✓ Branch 1 taken 11520 times.
37074 if (isdungeon(dmap, screen))
5939 {
5940
2/2
✓ Branch 0 taken 46080 times.
✓ Branch 1 taken 11520 times.
57600 for(int32_t i=0; i<4; i++)
5941 {
5942 46080 int32_t door=base_scr->door[i];
5943
5944
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36471 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46080 switch(door)
5945 {
5946 case d1WAYSHUTTER:
5947 case dSHUTTER:
5948
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
5949 {
5950 1694 base_scr->door[i]=dOPENSHUTTER;
5951 1694 }
5952
5953 5303 get_screen_state(screen).open_doors = -4;
5954 5303 break;
5955
5956 case dLOCKED:
5957
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5958 {
5959 1473 base_scr->door[i]=dUNLOCKED;
5960 1473 }
5961
5962 2372 break;
5963
5964 case dBOSS:
5965
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5966 {
5967 62 base_scr->door[i]=dOPENBOSS;
5968 62 }
5969
5970 230 break;
5971
5972 case dBOMB:
5973
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5974 {
5975 1087 base_scr->door[i]=dBOMBED;
5976 1087 }
5977
5978 1704 break;
5979 }
5980
5981 46080 update_door(base_scr, i, base_scr->door[i]);
5982
5983
4/4
✓ Branch 0 taken 41513 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40777 times.
46080 if(door==dSHUTTER||door==d1WAYSHUTTER)
5984 {
5985 5303 base_scr->door[i]=door;
5986 5303 }
5987 46080 }
5988 11520 }
5989
5990
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36937 times.
37074 if (!(base_scr->flags3 & fCYCLEONINIT))
5991 36937 return;
5992
5993
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
5994 {
5995
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
5996 {
5997 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
5998
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
5999 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6000
6001
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6002 {
6003 90464 int32_t c=layerscreen->data[i];
6004
6005 // New screen flag: Cycle Combos At Screen Init
6006
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6007 {
6008 65 int32_t r = 0;
6009
6010
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6011 {
6012 84 newcombo const& cmb = combobuf[c];
6013 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6015 84 layerscreen->data[i] = cid;
6016
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6018 84 c = layerscreen->data[i];
6019 }
6020 65 }
6021 90464 }
6022 514 }
6023 959 }
6024 37074 }
6025
6026 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6027 //
6028 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6029 // the game, etc...)
6030 //
6031 // Note: for regions, only the initial screen load calls this function. Simply walking between
6032 // screens in the same region does not use this, because every screen in a region is loaded into
6033 // temporary memory up front.
6034 //
6035 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6036 // `special_warp_return_scr`.
6037 //
6038 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6039 // on all layers (but only where the new screen has a 0 combo).
6040 //
6041 // TODO: loadscr should set curdmap, but currently callers do that.
6042 35830 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6043 {
6044 35830 zapp_reporting_set_tag("screen", screen);
6045
2/2
✓ Branch 0 taken 8917 times.
✓ Branch 1 taken 26913 times.
35830 if (destdmap != -1)
6046 8917 zapp_reporting_set_tag("dmap", destdmap);
6047
6048 35830 int32_t orig_destdmap = destdmap;
6049
2/2
✓ Branch 0 taken 8917 times.
✓ Branch 1 taken 26913 times.
35830 if (destdmap < 0) destdmap = cur_dmap;
6050
6051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35830 times.
35830 if (replay_is_active())
6052 {
6053
1/2
✓ Branch 0 taken 35830 times.
✗ Branch 1 not taken.
35830 if (replay_get_mode() == ReplayMode::ManualTakeover)
6054 replay_stop_manual_takeover();
6055
6056
2/2
✓ Branch 0 taken 26913 times.
✓ Branch 1 taken 8917 times.
35830 if (orig_destdmap != -1)
6057 {
6058
2/2
✓ Branch 0 taken 7844 times.
✓ Branch 1 taken 1073 times.
8917 if (strlen(DMaps[orig_destdmap].name) > 0)
6059 {
6060
1/2
✓ Branch 0 taken 7844 times.
✗ Branch 1 not taken.
7844 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6061 7844 }
6062 else
6063 {
6064
1/2
✓ Branch 0 taken 1073 times.
✗ Branch 1 not taken.
1073 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6065 }
6066 8917 }
6067 35830 replay_step_comment_loadscr(screen);
6068
6069 // Reset the rngs and frame count so that recording steps can be modified without impacting
6070 // behavior of later screens.
6071 35830 replay_sync_rng();
6072 35830 }
6073
6074
2/2
✓ Branch 0 taken 1707454 times.
✓ Branch 1 taken 35830 times.
1743284 for (auto& state : get_screen_states())
6075 1707454 state.second.triggered_secrets = false;
6076 35830 slopes.clear();
6077 35830 Hero.clear_platform_ffc();
6078 35830 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6079 35830 clear_darkroom_bitmaps();
6080 35830 msgscr = nullptr;
6081
6082
2/2
✓ Branch 0 taken 50387168 times.
✓ Branch 1 taken 35830 times.
50422998 for (word x=0; x<animated_combos; x++)
6083 {
6084
2/2
✓ Branch 0 taken 20919169 times.
✓ Branch 1 taken 29467999 times.
50387168 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6085 {
6086 20919169 combobuf[animated_combo_table4[x][0]].aclk = 0;
6087 20919169 }
6088 50387168 }
6089 35830 reset_combo_animations2();
6090 35830 region_is_lit = false;
6091
6092 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6093 // of the new ones.
6094 35830 bool origin_ffc_overlay = false;
6095
2/2
✓ Branch 0 taken 34700 times.
✓ Branch 1 taken 1130 times.
35830 if (origin_scr)
6096 {
6097
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34698 times.
34700 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6098 {
6099 34698 int c = origin_scr->numFFC();
6100
2/2
✓ Branch 0 taken 34554 times.
✓ Branch 1 taken 1038879 times.
1073433 for (int i = 0; i < c; i++)
6101 {
6102
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6103 {
6104 144 origin_ffc_overlay = true;
6105 144 break;
6106 }
6107 1038735 }
6108 34698 }
6109
6110
3/4
✓ Branch 0 taken 34700 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34556 times.
34700 if (origin_screen_overlay || origin_ffc_overlay)
6111 {
6112
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6113 {
6114 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6115
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6116 1008 prev_origin_scrs[i] = *prev_scr;
6117 else
6118 prev_origin_scrs[i] = {};
6119 1008 }
6120 144 }
6121 34700 }
6122
6123 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6124 // them, but scripts that need their data to persist will be removed.
6125 35830 loadscr_ffc_script_ids_to_remove.clear();
6126
2/2
✓ Branch 0 taken 20148880 times.
✓ Branch 1 taken 35830 times.
20184710 for (auto& key : scriptEngineDatas | std::views::keys)
6127 {
6128
2/2
✓ Branch 0 taken 19026975 times.
✓ Branch 1 taken 1121905 times.
20148880 if (key.first == ScriptType::FFC)
6129 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6130 }
6131
6132 35830 load_region(destdmap, screen);
6133
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34923 times.
35830 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6134 35830 hero_screen = screen;
6135
6136 35830 cpos_clear_all();
6137 35830 FFCore.deallocateAllScriptOwnedOfType(ScriptType::Screen);
6138 35830 FFCore.deallocateAllScriptOwnedOfType(ScriptType::Combo);
6139 35830 FFCore.clear_script_engine_data_of_type(ScriptType::Screen);
6140 35830 FFCore.clear_combo_scripts();
6141
6142
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35666 times.
35830 if (is_in_scrolling_region())
6143 {
6144
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6145 {
6146
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6147 {
6148
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6149
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6150 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6151 1408 }
6152 20992 }
6153 164 }
6154 else
6155 {
6156 35666 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6157 }
6158
6159 35830 prepare_current_region_handles();
6160
6161
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35666 times.
35830 if (is_in_scrolling_region())
6162 {
6163
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6164 {
6165
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6166 {
6167 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6168 1408 }
6169 20992 }
6170 164 }
6171 else
6172 {
6173 35666 load_a_screen_and_layers_post(destdmap, screen, ldir);
6174 }
6175
6176 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6177
2/2
✓ Branch 0 taken 34923 times.
✓ Branch 1 taken 907 times.
35830 if (screen >= 0x80)
6178
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6179
6180 35830 update_slope_comboposes();
6181 35830 cpos_force_update();
6182 35830 trig_trigger_groups();
6183
6184
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35830 times.
1157461 for (int index : loadscr_ffc_script_ids_to_remove)
6185 {
6186 1121631 FFCore.deallocateAllScriptOwned(ScriptType::FFC, index);
6187 1121631 FFCore.reset_script_engine_data(ScriptType::FFC, index);
6188 }
6189
6190 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6191 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6192 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6193 // It is up to the quest designer to make their subscreen be actually transparent.
6194 //
6195 // When not in "extended height mode" (otherwise 56 is 0):
6196 // - playing_field_offset: 56, but changes during earthquakes
6197 // - original_playing_field_offset: always 56
6198 //
6199 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6200 // - yofs of sprites
6201 // - bitmap y offsets in draw_screen
6202 // - drawing offsets for putscr, do_layer
6203 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6204 // - lots more
6205 //
6206 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6207
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35688 times.
35830 if (is_extended_height_mode())
6208 {
6209 142 playing_field_offset = 0;
6210 142 original_playing_field_offset = 0;
6211 // A few sprites exist as globals, so we must manually reset them.
6212 142 Hero.yofs = 0;
6213 142 mblock2.yofs = 0;
6214 142 }
6215 else
6216 {
6217 35688 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6218 35688 original_playing_field_offset = 56;
6219 }
6220 35830 is_any_room_dark = is_any_dark();
6221
6222 35830 game->load_portal();
6223 35830 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6224
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35795 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35830 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6225 {
6226 delete Hero.lift_wpn;
6227 Hero.lift_wpn = nullptr;
6228 }
6229
6230 35830 enemy_spawning_has_checked_been_here = false;
6231 35830 markBmap(-1, hero_screen);
6232 35830 Hero.maybe_begin_advanced_maze();
6233 35830 }
6234
6235 // Don't use this directly! Use `loadscr` instead.
6236 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6237 {
6238
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6239
6240 907 mapscr previous_scr = *special_warp_return_scr;
6241 907 mapscr* scr = special_warp_return_scr;
6242
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6243
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6244
6245
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6246 {
6247
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6248
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6249 else
6250 5059 special_warp_return_scrs[i] = {};
6251 5442 }
6252
6253 907 scr->valid |= mVALID; //layer 0 is always valid
6254
6255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6256 {
6257 scr->script = source->script;
6258 for ( int32_t q = 0; q < 8; q++ )
6259 {
6260 scr->screeninitd[q] = source->screeninitd[q];
6261 }
6262 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6263 }
6264 else
6265 {
6266 907 scr->script = 0;
6267 }
6268
6269
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6270 {
6271 for(int32_t c=0; c< 176; ++c)
6272 {
6273 if(scr->data[c]==0)
6274 {
6275 scr->data[c]=previous_scr.data[c];
6276 scr->sflag[c]=previous_scr.sflag[c];
6277 scr->cset[c]=previous_scr.cset[c];
6278 }
6279 }
6280
6281 for(int32_t i=0; i<6; i++)
6282 {
6283 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6284 {
6285 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6286 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6287
6288 for(int32_t c=0; c< 176; ++c)
6289 {
6290 if(TheMaps[lm].data[c]==0)
6291 {
6292 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6293 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6294 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6295 }
6296 }
6297 }
6298 }
6299 }
6300
6301
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6302
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6303
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6304 {
6305 28993 scr->ffcs[i].screen_spawned = screen;
6306
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6307
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6308 28993 }
6309
6310 907 int mi = mapind(cur_map, screen);
6311
6312 // Apply perm secrets, if applicable.
6313
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6314 {
6315
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6316 {
6317
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6318
6319
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6320
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6321 204 bool do_replay_comment = true;
6322 204 bool from_active_screen = false;
6323
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6324 204 }
6325
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6326 {
6327 for (int layer = 0; layer <= 6; layer++)
6328 {
6329 mapscr* tscr = &special_warp_return_scrs[layer];
6330 for (int pos = 0; pos < 176; pos++)
6331 {
6332 newcombo const* cmb = &combobuf[tscr->data[pos]];
6333 if(cmb->type == cLIGHTTARGET)
6334 {
6335 if(!(cmb->usrflags&cflag1)) //Unlit version
6336 {
6337 tscr->data[pos] += 1;
6338 }
6339 }
6340 }
6341 }
6342 }
6343 536 }
6344
6345 screen_handles_t screen_handles;
6346
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6347
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6348
6349
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6350
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6351
6352
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6353 {
6354
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6355 5 }
6356
6357
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6358 {
6359
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6360 1 }
6361
6362
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6363 {
6364 remove_chests(screen_handles);
6365 }
6366
6367
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6368 {
6369 remove_lockedchests(screen_handles);
6370 }
6371
6372
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6373 {
6374 remove_bosschests(screen_handles);
6375 }
6376
6377
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6378
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6379
6380
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
227771 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
6381 // This is duplicated 3 places... can this be reduced?
6382 226864 auto cid = handle.data();
6383 226864 auto* cmb = &handle.combo();
6384 226864 bool done = false;
6385 226864 std::set<int32_t> visited;
6386
2/4
✓ Branch 0 taken 226864 times.
✓ Branch 1 taken 226864 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
453728 while(!done)
6387 {
6388
2/8
✓ Branch 0 taken 226864 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 226864 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
226864 if(visited.contains(cid))
6389 {
6390 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
6391 break; // prevent infinite loop
6392 }
6393
1/4
✓ Branch 0 taken 226864 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
226864 visited.insert(cid);
6394
6395 226864 done = true; // don't loop again unless something changes
6396
2/4
✓ Branch 0 taken 226864 times.
✓ Branch 1 taken 531 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
227395 for(size_t idx = 0; idx < cmb->triggers.size(); ++idx)
6397 {
6398 531 auto& trig = cmb->triggers[idx];
6399
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 531 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
531 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
6400 do_trigger_combo(handle, idx);
6401 531 else continue; // can skip checking handle.data()
6402
6403 if(handle.data() != cid)
6404 {
6405 cid = handle.data();
6406 cmb = &handle.combo();
6407 done = false; // loop again for the new combo
6408 break;
6409 }
6410 }
6411 }
6412 226864 });
6413
6414 // check doors
6415
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6416 {
6417
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6418 {
6419 1484 int32_t door=scr->door[i];
6420
6421
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6422 {
6423 case d1WAYSHUTTER:
6424 case dSHUTTER:
6425
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6426 {
6427 scr->door[i]=dOPENSHUTTER;
6428 }
6429
6430
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6431 105 break;
6432
6433 case dLOCKED:
6434
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(1<<i))
6435 {
6436 80 scr->door[i]=dUNLOCKED;
6437 80 }
6438
6439 91 break;
6440
6441 case dBOSS:
6442
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(1<<i))
6443 {
6444 5 scr->door[i]=dOPENBOSS;
6445 5 }
6446
6447 9 break;
6448
6449 case dBOMB:
6450
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(1<<i))
6451 {
6452 51 scr->door[i]=dBOMBED;
6453 51 }
6454
6455 89 break;
6456 }
6457
6458
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6459
6460
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6461 {
6462 105 scr->door[i]=door;
6463 105 }
6464 1484 }
6465 371 }
6466
6467
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 625 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6468 {
6469
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6470 {
6471
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6472 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6473
6474
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6475 {
6476 224660 int32_t c=layerscreen->data[i];
6477
6478 // New screen flag: Cycle Combos At Screen Init
6479
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6480 {
6481 2380 int32_t r = 0;
6482
6483
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6484 {
6485 newcombo const& cmb = combobuf[c];
6486 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6487 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6488 layerscreen->data[i] = cid;
6489 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6490 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6491 c = layerscreen->data[i];
6492 }
6493 }
6494 227040 }
6495 3670 }
6496 6349 }
6497 5385 }
6498
6499 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6500 // instead returns an array of mapscr.
6501 // Used to draw/save the map.
6502 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6503 {
6504 45680 std::array<mapscr, 7> scrs;
6505 45680 mapscr* scr = &scrs[0];
6506
6507
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6508 {
6509
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6510 {
6511 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6512 32752496 }
6513 64716181 }
6514
6515
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6516
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6517 {
6518 scrs[0].valid = 0;
6519 return scrs;
6520 }
6521
6522
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6523
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6524 {
6525
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6526
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6527 else
6528 209266 scrs[i] = {};
6529 274080 }
6530
6531 screen_handles_t screen_handles;
6532
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6533
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6534
6535 45680 int mi = mapind(cur_map, screen);
6536
6537
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6538 {
6539
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6540 {
6541
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6542 5730 bool from_active_screen = false;
6543 5730 bool do_replay_comment = true;
6544
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6545 5730 }
6546
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6547 {
6548
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6549 {
6550 119 mapscr* tscr = &scrs[layer];
6551
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6552 {
6553 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6554
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6555 {
6556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6557 {
6558 17 tscr->data[pos] += 1;
6559 17 }
6560 17 }
6561 20944 }
6562 119 }
6563 17 }
6564 45626 }
6565
6566
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6567 {
6568
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6569 233 }
6570
6571
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6572 {
6573
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6574 1 }
6575
6576
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6577 {
6578
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6579 101 }
6580
6581
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6582 {
6583
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6584 24 }
6585
6586
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6587 {
6588 remove_bosschests(screen_handles);
6589 }
6590
6591
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6592
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6593
6594 // check doors
6595
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6596 {
6597
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6598 {
6599 216 int32_t door=scr->door[i];
6600 216 bool putit=true;
6601
6602
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6603 {
6604 case d1WAYSHUTTER:
6605 case dSHUTTER:
6606 61 break;
6607
6608 case dLOCKED:
6609
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(1<<i))
6610 {
6611 12 scr->door[i]=dUNLOCKED;
6612 12 }
6613
6614 12 break;
6615
6616 case dBOSS:
6617
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(1<<i))
6618 {
6619 scr->door[i]=dOPENBOSS;
6620 }
6621
6622 4 break;
6623
6624 case dBOMB:
6625 if(game->maps[mi]&(1<<i))
6626 {
6627 scr->door[i]=dBOMBED;
6628 }
6629
6630 break;
6631 }
6632
6633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6634 {
6635
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6636 216 }
6637
6638
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6639 {
6640 61 scr->door[i]=door;
6641 61 }
6642 216 }
6643 54 }
6644
6645
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6646 {
6647
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6648 {
6649
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6650 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6651
6652
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6653 {
6654 19446944 int32_t c=layerscreen->data[i];
6655
6656 // New screen flag: Cycle Combos At Screen Init
6657
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6658 {
6659 int32_t r = 0;
6660
6661 while(combobuf[c].can_cycle() && r++ < 10)
6662 {
6663 newcombo const& cmb = combobuf[c];
6664 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6665 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6666 layerscreen->data[i] = cid;
6667 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6668 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6669 c = layerscreen->data[i];
6670 }
6671 }
6672 19446944 }
6673 110494 }
6674 319760 }
6675
6676 45680 return scrs;
6677
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6678
6679 19001307 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6680 {
6681 // This is a bogus value while screenscrolling == true, but that's ok
6682 // because it is only used to calculate the rpos, and during screenscrolling
6683 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6684 // is always the same no matter the value of scr.
6685 19001307 int screen = get_screen_for_world_xy(x, y);
6686
6687 19001307 x -= viewport.x;
6688 19001307 y -= viewport.y;
6689
6690
3/6
✓ Branch 0 taken 19001307 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19001307 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19001307 times.
19001307 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6691 {
6692 rectfill(dest,x,y,x+255,y+175,0);
6693 return;
6694 }
6695
6696 37873704 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6697
2/2
✓ Branch 0 taken 128910 times.
✓ Branch 1 taken 18872397 times.
19001307 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6698
6699 int start_x, end_x, start_y, end_y;
6700 19001307 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6701
2/2
✓ Branch 0 taken 19001307 times.
✓ Branch 1 taken 202388759 times.
221390066 for (int cy = start_y; cy < end_y; cy++)
6702 {
6703
2/2
✓ Branch 0 taken 3073359042 times.
✓ Branch 1 taken 202388759 times.
3275747801 for (int cx = start_x; cx < end_x; cx++)
6704 {
6705 3073359042 int i = cx + cy*16;
6706
2/2
✓ Branch 0 taken 357691558 times.
✓ Branch 1 taken 2715667484 times.
3073359042 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6707 3073359042 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6708 3073359042 }
6709 202388759 }
6710 19001307 }
6711
6712 15526581 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6713 {
6714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if (!show_layers[0])
6715 {
6716 return;
6717 }
6718
6719 15526581 x -= viewport.x;
6720 15526581 y -= viewport.y;
6721
6722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6723 15662899 mapscr* scr = screen_handles[0].base_scr;
6724
1/2
✓ Branch 0 taken 15662899 times.
✗ Branch 1 not taken.
15662899 if (!scr->is_valid())
6725 return;
6726
6727
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15539488 times.
15662899 if(scr->door[0]==dBOMBED)
6728 {
6729 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6730 123411 }
6731
6732
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15519790 times.
15662899 if(scr->door[1]==dBOMBED)
6733 {
6734 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6735 143109 }
6736
6737
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15507037 times.
15662899 if(scr->door[2]==dBOMBED)
6738 {
6739 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6740 155862 }
6741
6742
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15530610 times.
15662899 if(scr->door[3]==dBOMBED)
6743 {
6744 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6745 132289 }
6746 15662899 });
6747 15526581 }
6748
6749 3338408 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6750 {
6751
2/4
✓ Branch 0 taken 3338408 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3338408 times.
✗ Branch 3 not taken.
3338408 if (!scr->is_valid() || !show_layers[0])
6752 return;
6753
6754 3338408 x -= viewport.x;
6755 3338408 y -= viewport.y;
6756
6757
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3300752 times.
3338408 if(scr->door[0]==dBOMBED)
6758 {
6759 37656 over_door(scr,dest,39,up,x,y);
6760 37656 }
6761
6762
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3301913 times.
3338408 if(scr->door[1]==dBOMBED)
6763 {
6764 36495 over_door(scr,dest,135,down,x,y);
6765 36495 }
6766
6767
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3297968 times.
3338408 if(scr->door[2]==dBOMBED)
6768 {
6769 40440 over_door(scr,dest,66,left,x,y);
6770 40440 }
6771
6772
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3301345 times.
3338408 if(scr->door[3]==dBOMBED)
6773 {
6774 37063 over_door(scr,dest,77,right,x,y);
6775 37063 }
6776 3338408 }
6777 231354425 static inline bool onSwitch(newcombo const& cmb, zfix const& switchblockstate)
6778 {
6779
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 231354425 times.
✓ Branch 2 taken 231340696 times.
✓ Branch 3 taken 13729 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13729 times.
231354425 return (switchblockstate < 0 || (cmb.attributes[2]>0 && (zslongToFix(cmb.attributes[2]) - zslongToFix(zc_max(cmb.attributes[3], 0))) <=switchblockstate));
6780 }
6781 55812276 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6782 {
6783 55812276 return _walkflag(zx,zy,cnt,0_zf);
6784 }
6785
6786 132306538 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& switchblockstate, bool is_temp_screens)
6787 {
6788 132306538 int x = zx.getRound(), y = zy.getRound();
6789 132306538 int pos = COMBOPOS(x % 256, y % 176);
6790 132306538 const newcombo& c = combobuf[s0->data[pos]];
6791 132306538 const newcombo& c1 = combobuf[s1->data[pos]];
6792 132306538 const newcombo& c2 = combobuf[s2->data[pos]];
6793
4/4
✓ Branch 0 taken 130314083 times.
✓ Branch 1 taken 1992455 times.
✓ Branch 2 taken 130304623 times.
✓ Branch 3 taken 9460 times.
264815364 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6794
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 130405758 times.
✓ Branch 2 taken 2098823 times.
✓ Branch 3 taken 4245 times.
132306538 (iswater_type(c2.type))) && DRIEDLAKE);
6795 132508826 int32_t b=1;
6796
2/2
✓ Branch 0 taken 65319932 times.
✓ Branch 1 taken 67188894 times.
132508826 if(x&8) b<<=2;
6797
2/2
✓ Branch 0 taken 61875148 times.
✓ Branch 1 taken 70633678 times.
132508826 if(y&8) b<<=1;
6798
6799 132508826 int32_t cwalkflag = c.walk;
6800
3/8
✓ Branch 0 taken 132407682 times.
✓ Branch 1 taken 101144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 132407682 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
132508826 if(is_temp_screens && onSwitch(c,switchblockstate) && c.type == cCSWITCHBLOCK && c.usrflags&cflag9) cwalkflag &= (c.walk>>4)^0xF;
6801
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 132458254 times.
✓ Branch 2 taken 2093599 times.
✓ Branch 3 taken 2043027 times.
✓ Branch 4 taken 2093599 times.
✓ Branch 5 taken 132407682 times.
✓ Branch 6 taken 2093599 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2093599 times.
✗ Branch 9 not taken.
132508826 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6802
2/2
✓ Branch 0 taken 63161240 times.
✓ Branch 1 taken 69246442 times.
132407682 if (s1 != s0)
6803 {
6804
2/8
✓ Branch 0 taken 69246442 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 69246442 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69246442 if(is_temp_screens && onSwitch(c1,switchblockstate) && c1.type == cCSWITCHBLOCK && c1.usrflags&cflag9) cwalkflag &= (c1.walk>>4)^0xF;
6805
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69234713 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69246442 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6806
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69183536 times.
69246442 else if (c1.type == cBRIDGE)
6807 {
6808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6809 {
6810 62906 int efflag = (c1.walk & 0xF0)>>4;
6811 62906 int newsolid = (c1.walk & 0xF);
6812 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6813 62906 }
6814 else cwalkflag &= c1.walk;
6815 62906 }
6816
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69171807 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69183536 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6817 69183536 else cwalkflag |= c1.walk;
6818 69246442 }
6819
2/2
✓ Branch 0 taken 102707381 times.
✓ Branch 1 taken 29700301 times.
132407682 if (s2 != s0)
6820 {
6821
2/8
✓ Branch 0 taken 29700301 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29700301 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29700301 if(is_temp_screens && onSwitch(c2,switchblockstate) && c2.type == cCSWITCHBLOCK && c2.usrflags&cflag9) cwalkflag &= (c2.walk>>4)^0xF;
6822
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29698147 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29700301 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6823
2/2
✓ Branch 0 taken 1310 times.
✓ Branch 1 taken 29698991 times.
29700301 else if (c2.type == cBRIDGE)
6824 {
6825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1310 times.
1310 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6826 {
6827 1310 int efflag = (c2.walk & 0xF0)>>4;
6828 1310 int newsolid = (c2.walk & 0xF);
6829 1310 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6830 1310 }
6831 else cwalkflag &= c2.walk;
6832 1310 }
6833
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29696837 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29698991 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6834 29698991 else cwalkflag |= c2.walk;
6835 29700301 }
6836
6837
4/4
✓ Branch 0 taken 29538102 times.
✓ Branch 1 taken 102869580 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29537154 times.
132407682 if((cwalkflag&b) && !dried)
6838 29537154 return true;
6839
6840
3/4
✓ Branch 0 taken 102870528 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102854117 times.
✓ Branch 3 taken 16411 times.
102870528 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6841
6842 102854117 return false;
6843 132407682 }
6844
6845 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6846 132407682 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& switchblockstate)
6847 {
6848 132407682 int x = zx.getRound(), y = zy.getRound();
6849 132407682 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6850 132407682 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6851 132407682 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6852
2/2
✓ Branch 0 taken 63161240 times.
✓ Branch 1 taken 69246442 times.
132407682 if (!s1->valid) s1 = s0;
6853
2/2
✓ Branch 0 taken 102707381 times.
✓ Branch 1 taken 29700301 times.
132407682 if (!s2->valid) s2 = s0;
6854 132407682 return _walkflag_new(s0, s1, s2, zx, zy, switchblockstate, true);
6855 }
6856
6857 128204686 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& switchblockstate)
6858 {
6859 128204686 int max_x = world_w;
6860 128204686 int max_y = world_h;
6861
2/2
✓ Branch 0 taken 68297999 times.
✓ Branch 1 taken 59906687 times.
128204686 if (!get_qr(qr_LTTPWALK))
6862 {
6863 59906687 max_x -= 7;
6864 59906687 max_y -= 7;
6865 59906687 }
6866
4/4
✓ Branch 0 taken 127933866 times.
✓ Branch 1 taken 270820 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 127850598 times.
128204686 if (x < 0 || y < 0) return false;
6867
2/2
✓ Branch 0 taken 322238 times.
✓ Branch 1 taken 127528360 times.
127850598 if (x >= max_x) return false;
6868
3/4
✓ Branch 0 taken 539458 times.
✓ Branch 1 taken 126988902 times.
✓ Branch 2 taken 539458 times.
✗ Branch 3 not taken.
127528360 if (x >= max_x - 8 && cnt == 2) return false;
6869
2/2
✓ Branch 0 taken 126979158 times.
✓ Branch 1 taken 549202 times.
127528360 if (y >= max_y) return false;
6870
6871
4/4
✓ Branch 0 taken 29435405 times.
✓ Branch 1 taken 97543753 times.
✓ Branch 2 taken 92115229 times.
✓ Branch 3 taken 5428524 times.
126979158 return _walkflag_new(x, y, switchblockstate) || (cnt != 1 && _walkflag_new(x + 8, y, switchblockstate));
6872 128204686 }
6873
6874 99017955 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6875 {
6876 99017955 mapscr* s0 = get_scr_for_world_xy(x, y);
6877 99017955 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6878 99017955 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6879
2/2
✓ Branch 0 taken 51391831 times.
✓ Branch 1 taken 47626124 times.
99017955 if (!s1->valid) s1 = s0;
6880
2/2
✓ Branch 0 taken 17530096 times.
✓ Branch 1 taken 81487859 times.
99017955 if (!s2->valid) s2 = s0;
6881
6882 99017955 int pos = COMBOPOS(x % 256, y % 176);
6883 99017955 const newcombo& c = combobuf[s0->data[pos]];
6884 99017955 const newcombo& c1 = combobuf[s1->data[pos]];
6885 99017955 const newcombo& c2 = combobuf[s2->data[pos]];
6886
4/4
✓ Branch 0 taken 98090677 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98089311 times.
✓ Branch 3 taken 1366 times.
198035910 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6887
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98089311 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99017955 (iswater_type(c2.type))) && DRIEDLAKE);
6888 99017955 int32_t b=1;
6889
2/2
✓ Branch 0 taken 49817649 times.
✓ Branch 1 taken 49200306 times.
99017955 if(x&8) b<<=2;
6890
2/2
✓ Branch 0 taken 41760540 times.
✓ Branch 1 taken 57257415 times.
99017955 if(y&8) b<<=1;
6891
6892 99017955 int32_t cwalkflag = (c.walk>>4);
6893
2/2
✓ Branch 0 taken 76265628 times.
✓ Branch 1 taken 22752327 times.
99017955 if (layer == 0) cwalkflag = (c1.walk>>4);
6894
2/2
✓ Branch 0 taken 76266616 times.
✓ Branch 1 taken 22751339 times.
99017955 if (layer == 1) cwalkflag = (c2.walk>>4);
6895 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6896
4/4
✓ Branch 0 taken 51391831 times.
✓ Branch 1 taken 47626124 times.
✓ Branch 2 taken 22423002 times.
✓ Branch 3 taken 28968829 times.
99017955 if (s1 != s0 && layer < 0)
6897 {
6898
2/2
✓ Branch 0 taken 22409596 times.
✓ Branch 1 taken 13406 times.
22423002 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6899 22423002 }
6900
4/4
✓ Branch 0 taken 17530096 times.
✓ Branch 1 taken 81487859 times.
✓ Branch 2 taken 13009719 times.
✓ Branch 3 taken 4520377 times.
99017955 if (s2 != s0 && layer < 1)
6901 {
6902
2/2
✓ Branch 0 taken 13009367 times.
✓ Branch 1 taken 352 times.
13009719 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6903 13009719 }
6904
6905
2/2
✓ Branch 0 taken 98864209 times.
✓ Branch 1 taken 153746 times.
99017955 return (cwalkflag&b) ? !dried : false;
6906 }
6907
6908 99392839 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6909 {
6910 DCHECK(cnt == 0 || cnt == 1);
6911 99392839 int max_x = world_w;
6912 99392839 int max_y = world_h;
6913
3/4
✓ Branch 0 taken 45832191 times.
✓ Branch 1 taken 53560648 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45832191 times.
99392839 if (!get_qr(qr_LTTPWALK) && !notLink)
6914 {
6915 45832191 max_x -= 7;
6916 45832191 max_y -= 7;
6917 45832191 }
6918
4/4
✓ Branch 0 taken 99392086 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99391882 times.
99392839 if (x < 0 || y < 0) return false;
6919
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99391064 times.
99391882 if (x >= max_x) return false;
6920
3/4
✓ Branch 0 taken 521750 times.
✓ Branch 1 taken 98869314 times.
✓ Branch 2 taken 521750 times.
✗ Branch 3 not taken.
99391064 if (x >= max_x - 8 && cnt == 2) return false;
6921
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99017955 times.
99391064 if (y >= max_y) return false;
6922
6923
3/4
✓ Branch 0 taken 98863419 times.
✓ Branch 1 taken 154536 times.
✓ Branch 2 taken 154536 times.
✗ Branch 3 not taken.
99017955 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6924 99392839 }
6925
6926 // used by mapdata->isSolid(x,y) in ZScript
6927 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6928 {
6929 int x = zx.getRound(), y = zy.getRound();
6930 {
6931 int max_x = 256;
6932 int max_y = 176;
6933 if (!get_qr(qr_LTTPWALK))
6934 {
6935 max_x -= 7;
6936 max_y -= 7;
6937 }
6938 if (x < 0 || y < 0) return false;
6939 if (x >= max_x) return false;
6940 if (x >= max_x - 8 && cnt == 2) return false;
6941 if (y >= max_y) return false;
6942 }
6943
6944 const mapscr *s1, *s2;
6945
6946 if ( m->layermap[0] > 0 )
6947 {
6948 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
6949 }
6950 else s1 = m;
6951
6952 if ( m->layermap[1] > 0 )
6953 {
6954 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
6955 }
6956 else s2 = m;
6957
6958 zfix unused;
6959 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
6960 }
6961
6962 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
6963 {
6964 DCHECK_LAYER_NEG1_INDEX(layer);
6965 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
6966 if (!m->is_valid()) return false;
6967 return _walkflag_layer(x, y, cnt, m);
6968 }
6969
6970 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
6971 {
6972 int x = zx.getRound(), y = zy.getRound();
6973
6974 if (!get_qr(qr_LTTPWALK))
6975 {
6976 max_x -= 7;
6977 max_y -= 7;
6978 }
6979 if (x < 0 || y < 0) return false;
6980 if (x >= max_x) return false;
6981 if (x >= max_x - 8 && cnt == 2) return false;
6982 if (y >= max_y) return false;
6983
6984 if(!m) return true;
6985
6986 int pos = COMBOPOS(x%256, y%176);
6987 const newcombo* c = &combobuf[m->data[pos]];
6988 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
6989 int32_t b=1;
6990
6991 if(x&8) b<<=2;
6992
6993 if(y&8) b<<=1;
6994
6995 if((c->walk&b) && !dried)
6996 return true;
6997
6998 if(cnt==1) return false;
6999
7000 ++pos;
7001
7002 if(!(x&8))
7003 b<<=2;
7004 else
7005 {
7006 c = &combobuf[m->data[pos]];
7007 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7008 b=1;
7009
7010 if(y&8) b<<=1;
7011 }
7012
7013 return (c->walk&b) ? !dried : false;
7014 }
7015
7016 //Only check the given mapscr*, not its layer 1&2
7017 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7018 {
7019 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7020 }
7021
7022 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7023 {
7024 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7025 }
7026
7027 261239 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7028 {
7029 DCHECK_LAYER_NEG1_INDEX(layer);
7030 261239 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7031
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 259477 times.
261239 if (!m->is_valid()) return false;
7032 259477 return _effectflag_layer(x, y, cnt, m, notLink);
7033 261239 }
7034
7035 322275 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7036 {
7037 322275 int max_x = world_w;
7038 322275 int max_y = world_h;
7039
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 272273 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
322275 if (!get_qr(qr_LTTPWALK) && !notLink)
7040 {
7041 max_x -= 7;
7042 max_y -= 7;
7043 }
7044
2/4
✓ Branch 0 taken 322275 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 322275 times.
322275 if (x < 0 || y < 0) return false;
7045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 322275 times.
322275 if (x >= max_x) return false;
7046
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 321066 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
322275 if (x >= max_x - 8 && cnt == 2) return false;
7047
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 322275 times.
322275 if (y >= max_y) return false;
7048
7049
1/2
✓ Branch 0 taken 322275 times.
✗ Branch 1 not taken.
322275 if (!m) return true;
7050
7051 322275 int pos = COMBOPOS(x%256, y%176);
7052 322275 const newcombo* c = &combobuf[m->data[pos]];
7053
3/4
✓ Branch 0 taken 321894 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
322656 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7054 322275 int32_t b=1;
7055
7056
2/2
✓ Branch 0 taken 178894 times.
✓ Branch 1 taken 143381 times.
322275 if(x&8) b<<=2;
7057
7058
2/2
✓ Branch 0 taken 135815 times.
✓ Branch 1 taken 186460 times.
322275 if(y&8) b<<=1;
7059
7060
3/4
✓ Branch 0 taken 253281 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 253281 times.
322275 if(((c->walk>>4)&b) && !dried)
7061 253281 return true;
7062
7063
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7064
7065 ++pos;
7066
7067 if(!(x&8))
7068 b<<=2;
7069 else
7070 {
7071 c = &combobuf[m->data[pos]];
7072 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7073 b=1;
7074
7075 if(y&8) b<<=1;
7076 }
7077
7078 return ((c->walk>>4)&b) ? !dried : false;
7079 322275 }
7080
7081 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7082 {
7083 812605 int max_x = world_w;
7084 812605 int max_y = world_h;
7085
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7086 {
7087 695238 max_x -= 7;
7088 695238 max_y -= 7;
7089 695238 }
7090
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7092
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7094
7095
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7096 812605 }
7097
7098 812605 bool water_walkflag(int32_t x, int32_t y)
7099 {
7100 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7101 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7102 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7103
7104 812605 int32_t b=1;
7105
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7107
7108
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7109 {
7110
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7111 132 return true;
7112
7113
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7114 292 return true;
7115
7116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7117 return true;
7118 25953 }
7119 else
7120 {
7121
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7122 16371 return true;
7123
7124
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7125 17 return true;
7126
7127
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7128 13 return true;
7129 }
7130
7131 795780 return false;
7132 812605 }
7133
7134 563892 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7135 {
7136
2/2
✓ Branch 0 taken 90807 times.
✓ Branch 1 taken 473085 times.
563892 if(dlevel)
7137
8/8
✓ Branch 0 taken 471680 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468485 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466825 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462626 times.
473085 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7138 10459 return true;
7139
7140
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553431 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553433 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7141 return true;
7142
7143
8/8
✓ Branch 0 taken 553164 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 552931 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552722 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552376 times.
553433 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7144 1057 return true;
7145
7146 // for(int32_t i=0; i<4; i++)
7147
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551535 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552376 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7148 36 return true;
7149
7150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552340 times.
552340 if (collide_object(x, y,cnt*8, 1))
7151 return true;
7152
7153 552340 return _walkflag(x,y,cnt);
7154 563892 }
7155
7156 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7157 {
7158 // 16 pixel buffer to account for slopes that are on bordering screens.
7159
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7160 return true;
7161
7162 // for(int32_t i=0; i<4; i++)
7163
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7164 return true;
7165
7166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7167 return true;
7168
7169 12110 return _walkflag(x,y,cnt);
7170 12110 }
7171
7172 37813 void map_bkgsfx(bool on)
7173 {
7174
2/2
✓ Branch 0 taken 37792 times.
✓ Branch 1 taken 21 times.
37813 if(on)
7175 {
7176 37792 cont_sfx(hero_scr->oceansfx);
7177
7178
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37423 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37792 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7179 315 cont_sfx(hero_scr->bosssfx);
7180 37792 }
7181 else
7182 {
7183 21 adjust_sfx(hero_scr->oceansfx,128,false);
7184 21 adjust_sfx(hero_scr->bosssfx,128,false);
7185
7186
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7187 {
7188
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7189 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7190 114 }
7191 }
7192 37813 }
7193
7194 239 void toggle_switches(dword flags, bool entry)
7195 {
7196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7197
7198 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7199 239 toggle_switches(flags, entry, create_screen_handles(scr));
7200 239 });
7201 239 }
7202 54016 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7203 {
7204
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53279 times.
54016 if(!flags) return; //No flags to toggle
7205
7206 737 mapscr* m = screen_handles[0].base_scr;
7207 737 int screen = m->screen;
7208 737 bool is_active_screen = is_in_current_region(m);
7209
7210 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7211 304304 byte togglegrid[176] = {0};
7212 304304 mapscr* scr = rpos_handle.scr;
7213 304304 int lyr = rpos_handle.layer;
7214 304304 int pos = rpos_handle.pos;
7215 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7216
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7217
2/2
✓ Branch 0 taken 264880 times.
✓ Branch 1 taken 102893 times.
367773 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7218 {
7219 102893 auto& trig = cmb.triggers[idx];
7220
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 if((trig.triggerflags[3] & combotriggerTRIGLEVELSTATE) && trig.trig_lstate < 32)
7221 if(flags&(1<<trig.trig_lstate))
7222 {
7223 auto oldcombo = rpos_handle.data();
7224 do_trigger_combo(rpos_handle, idx, ctrigSWITCHSTATE);
7225 if(rpos_handle.data() != oldcombo) break;
7226 }
7227 367773 }
7228
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7229
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7230 {
7231
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7232 {
7233 2314 set<int32_t> oldData;
7234 //Increment the combo/cset by the attributes
7235 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7236 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7237
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7238
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7239 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7240
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7241 {
7242 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7243
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7244 {
7245 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7246 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7247 if(oldData.find(cid) != oldData.end())
7248 break;
7249
7250 scr->data[pos] = cid;
7251 if(!(tmp->animflags & AF_CYCLENOCSET))
7252 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7253 oldData.insert(cid);
7254 tmp = &combobuf[cid];
7255 }
7256 238 }
7257 2314 int32_t cmbid = scr->data[pos];
7258
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7259 {
7260 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7261 41 combobuf[cmbid].cur_frame=0;
7262 41 combobuf[cmbid].aclk = 0;
7263
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7264 41 }
7265 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7266
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7268 {
7269
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7270
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7271
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7272
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7273
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7274 return;
7275 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7276
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7277 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7278 return; //This is a switch/block that will be hit later in the loop!
7279 344 set<int32_t> oldData2;
7280 //Increment the combo/cset by the original cmb's attributes
7281
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7282
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7283 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7284
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7285 {
7286 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7287 while(tmp->can_cycle())
7288 {
7289 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7290 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7291 if(oldData2.find(cid) != oldData2.end())
7292 break;
7293
7294 scr_2->data[pos] = cid;
7295 if(!(tmp->animflags & AF_CYCLENOCSET))
7296 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7297 oldData2.insert(cid);
7298 tmp = &combobuf[cid];
7299 }
7300 }
7301 344 int32_t cmbid2 = scr_2->data[pos];
7302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7303 {
7304 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7305 combobuf[cmbid2].cur_frame=0;
7306 combobuf[cmbid2].aclk = 0;
7307 combo_caches::drawing.refresh(cmbid2);
7308 }
7309 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7310 344 }
7311
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7312 446 }
7313 304304 });
7314
7315
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7316 {
7317 newcombo const& cmb = combobuf[mblock2.bcombo];
7318 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7319 {
7320 if(flags&(1<<cmb.attribytes[0]))
7321 {
7322 //Increment the combo/cset by the attributes
7323 int32_t cmbofs = (cmb.attributes[0]/10000L);
7324 int32_t csofs = (cmb.attributes[1]/10000L);
7325 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7326 mblock2.cs = (mblock2.cs + csofs) & 15;
7327 int32_t cmbid = mblock2.bcombo;
7328 if(combobuf[cmbid].animflags & AF_CYCLE)
7329 {
7330 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7331 combobuf[cmbid].cur_frame=0;
7332 combobuf[cmbid].aclk = 0;
7333 combo_caches::drawing.refresh(cmbid);
7334 }
7335 }
7336 }
7337 }
7338
7339
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7340 {
7341 513 int screen_index_offset = get_region_screen_offset(m->screen);
7342 513 word c = m->numFFC();
7343
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7344 {
7345 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7346 334 auto& cmb = ffc_handle.combo();
7347
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 29 times.
363 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7348 {
7349 29 auto& trig = cmb.triggers[idx];
7350
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 if((trig.triggerflags[3] & combotriggerTRIGLEVELSTATE) && trig.trig_lstate < 32)
7351 if(flags&(1<<trig.trig_lstate))
7352 {
7353 auto oldcombo = ffc_handle.data();
7354 do_trigger_combo(ffc_handle, idx, ctrigSWITCHSTATE);
7355 if(ffc_handle.data() != oldcombo) break;
7356 }
7357 29 }
7358 334 }
7359 513 }
7360 54016 }
7361
7362 void toggle_gswitches(int32_t state, bool entry)
7363 {
7364 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7365 toggle_gswitches(state, entry, create_screen_handles(scr));
7366 });
7367 }
7368 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7369 {
7370 bool states[256] = {false};
7371 states[state] = true;
7372 toggle_gswitches(states, entry, screen_handles);
7373 }
7374 15204141 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7375 {
7376
1/2
✓ Branch 0 taken 15204141 times.
✗ Branch 1 not taken.
15204141 if(!states) return;
7377
7378 15204141 auto& combo_cache = combo_caches::gswitch;
7379 15204141 mapscr* base_scr = screen_handles[0].base_scr;
7380 15204141 int screen = base_scr->screen;
7381 15204141 bool is_active_screen = is_in_current_region(base_scr);
7382 15204141 byte togglegrid[176] = {0};
7383
2/2
✓ Branch 0 taken 15204141 times.
✓ Branch 1 taken 106428987 times.
121633128 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7384 {
7385 106428987 mapscr* scr = screen_handles[lyr].scr;
7386
2/2
✓ Branch 0 taken 74161861 times.
✓ Branch 1 taken 32267126 times.
106428987 if (!scr)
7387 74161861 continue;
7388
7389
2/2
✓ Branch 0 taken 5679014176 times.
✓ Branch 1 taken 32267126 times.
5711281302 for(int32_t pos = 0; pos < 176; ++pos)
7390 {
7391 5679014176 int cid = scr->data[pos];
7392 5679014176 auto& mini_cmb = combo_cache.minis[cid];
7393
7394
2/2
✓ Branch 0 taken 93474656 times.
✓ Branch 1 taken 5585539520 times.
5679014176 if (is_active_screen)
7395 {
7396
2/2
✓ Branch 0 taken 5585537638 times.
✓ Branch 1 taken 1882 times.
5585539520 if (mini_cmb.trigger_global_state)
7397 {
7398 1882 auto& cmb = combobuf[cid];
7399
2/2
✓ Branch 0 taken 1882 times.
✓ Branch 1 taken 1882 times.
3764 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7400 {
7401 1882 auto& trig = cmb.triggers[idx];
7402
2/4
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1882 times.
✗ Branch 3 not taken.
1882 if ((trig.triggerflags[3] & combotriggerTRIGGLOBALSTATE) && states[trig.trig_gstate])
7403 {
7404 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7405 do_trigger_combo(rpos_handle, idx, ctrigSWITCHSTATE);
7406 if(rpos_handle.data() != cid) break;
7407 }
7408 1882 }
7409 1882 }
7410 5585539520 }
7411
7412
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5678973781 times.
5679014176 if (!mini_cmb.has_global_state)
7413 5678973781 continue;
7414
7415 40395 newcombo const& cmb = combobuf[cid];
7416
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7417 {
7418 if(states[cmb.attribytes[0]])
7419 {
7420 set<int32_t> oldData;
7421 //Increment the combo/cset by the attributes
7422 int32_t cmbofs = (cmb.attributes[0]/10000L);
7423 int32_t csofs = (cmb.attributes[1]/10000L);
7424 oldData.insert(scr->data[pos]);
7425 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7426 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7427 if(entry && (cmb.usrflags&cflag8))
7428 {
7429 newcombo const* tmp = &combobuf[scr->data[pos]];
7430 while(tmp->can_cycle())
7431 {
7432 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7433 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7434 if(oldData.find(cid) != oldData.end())
7435 break;
7436 scr->data[pos] = cid;
7437 if(!(tmp->animflags & AF_CYCLENOCSET))
7438 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7439 oldData.insert(cid);
7440 tmp = &combobuf[cid];
7441 }
7442 }
7443 int32_t cmbid = scr->data[pos];
7444 if(combobuf[cmbid].animflags & AF_CYCLE)
7445 {
7446 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7447 combobuf[cmbid].cur_frame=0;
7448 combobuf[cmbid].aclk = 0;
7449 combo_caches::drawing.refresh(cmbid);
7450 }
7451 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7452 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7453 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7454 {
7455 if(lyr==lyr2) continue;
7456 if(!(cmb.usrflags&(1<<lyr2))) continue;
7457 if(togglegrid[pos]&(1<<lyr2)) continue;
7458 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7459 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7460 continue;
7461 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7462 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7463 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7464 continue; //This is a switch/block that will be hit later in the loop!
7465 set<int32_t> oldData2;
7466 //Increment the combo/cset by the original cmb's attributes
7467 oldData2.insert(scr_2->data[pos]);
7468 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7469 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7470 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7471 {
7472 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7473 while(tmp->can_cycle())
7474 {
7475 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7476 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7477 if(oldData2.find(cid) != oldData2.end())
7478 break;
7479 scr_2->data[pos] = cid;
7480 if(!(tmp->animflags & AF_CYCLENOCSET))
7481 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7482 oldData2.insert(cid);
7483 tmp = &combobuf[cid];
7484 }
7485 }
7486 int32_t cmbid2 = scr_2->data[pos];
7487 if(combobuf[cmbid2].animflags & AF_CYCLE)
7488 {
7489 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7490 combobuf[cmbid2].cur_frame=0;
7491 combobuf[cmbid2].aclk = 0;
7492 combo_caches::drawing.refresh(cmbid2);
7493 }
7494 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7495 }
7496 }
7497 }
7498 40395 }
7499 32267126 }
7500
7501
4/4
✓ Branch 0 taken 535280 times.
✓ Branch 1 taken 14668861 times.
✓ Branch 2 taken 4744 times.
✓ Branch 3 taken 530536 times.
15204141 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7502 {
7503 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7504
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7505 {
7506 if(states[cmb.attribytes[0]])
7507 {
7508 //Increment the combo/cset by the attributes
7509 int32_t cmbofs = (cmb.attributes[0]/10000L);
7510 int32_t csofs = (cmb.attributes[1]/10000L);
7511 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7512 mblock2.cs = (mblock2.cs + csofs) & 15;
7513 int32_t cmbid = mblock2.bcombo;
7514 if(combobuf[cmbid].animflags & AF_CYCLE)
7515 {
7516 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7517 combobuf[cmbid].cur_frame=0;
7518 combobuf[cmbid].aclk = 0;
7519 combo_caches::drawing.refresh(cmbid);
7520 }
7521 }
7522 }
7523 4744 }
7524
7525
2/2
✓ Branch 0 taken 413475 times.
✓ Branch 1 taken 14790666 times.
15204141 if(is_active_screen)
7526 {
7527 14790666 int screen_index_offset = get_region_screen_offset(screen);
7528 14790666 word c = base_scr->numFFC();
7529
2/2
✓ Branch 0 taken 441779442 times.
✓ Branch 1 taken 14790666 times.
456570108 for (int q = 0; q < c; ++q)
7530 {
7531 441779442 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7532 441779442 int cid = ffc_handle.data();
7533 // auto& mini_cmb = combo_cache.minis[cid];
7534 // if (mini_cmb.trigger_global_state)
7535 441779442 auto& cmb = combobuf[cid];
7536
2/2
✓ Branch 0 taken 441779442 times.
✓ Branch 1 taken 228788 times.
442008230 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7537 {
7538 228788 auto& trig = cmb.triggers[idx];
7539
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 if (states[trig.trig_gstate])
7540 do_trigger_combo(ffc_handle, idx, ctrigSWITCHSTATE);
7541
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 if(ffc_handle.data() != cid) break;
7542 228788 }
7543 441779442 }
7544 14790666 }
7545 15204141 }
7546 53777 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7547 {
7548 bool states[256];
7549
2/2
✓ Branch 0 taken 13766912 times.
✓ Branch 1 taken 53777 times.
13820689 for(auto q = 0; q < 256; ++q)
7550 {
7551 13766912 states[q] = game->gswitch_timers[q] != 0;
7552 13766912 }
7553 53777 toggle_gswitches(states, true, screen_handles);
7554 53777 }
7555 14760996 void run_gswitch_timers()
7556 {
7557 14760996 bool states[256] = {false};
7558 14760996 auto& m = game->gswitch_timers.mut_inner();
7559
2/2
✓ Branch 0 taken 3774772736 times.
✓ Branch 1 taken 14760996 times.
3789533732 for(auto it = m.begin(); it != m.end();)
7560 {
7561
1/2
✓ Branch 0 taken 3774772736 times.
✗ Branch 1 not taken.
3774772736 if(it->second > 0)
7562 if(!--it->second)
7563 {
7564 states[it->first] = true;
7565 it = m.erase(it);
7566 continue;
7567 }
7568 3774772736 ++it;
7569 }
7570 29911360 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7571 15150364 toggle_gswitches(states, false, create_screen_handles(scr));
7572 15150364 });
7573 14760996 }
7574 1109 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7575 {
7576
2/2
✓ Branch 0 taken 283904 times.
✓ Branch 1 taken 1109 times.
285013 for(auto q = 0; q < 256; ++q)
7577 {
7578
1/2
✓ Branch 0 taken 283904 times.
✗ Branch 1 not taken.
283904 if(game->gswitch_timers[q] > 0)
7579 game->gswitch_timers[q] = 0;
7580 283904 }
7581 1109 }
7582
7583 /**** View Map ****/
7584
7585 int32_t mapres = 0;
7586 int32_t view_map_show_mode = 3;
7587
7588 124544 bool displayOnMap(int32_t x, int32_t y)
7589 {
7590 124544 int32_t s = (y<<4) + x;
7591 124544 int mi = mapind(cur_map, s);
7592
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7593 67891 return false;
7594
7595 // Don't display if not part of DMap
7596
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7597
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7598
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7599
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7600 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7601 10973 return false;
7602 else
7603 45680 return true;
7604 124544 }
7605
7606 973 void ViewMap()
7607 {
7608 973 ViewingMap = true;
7609
7610 973 BITMAP* mappic = NULL;
7611 static double scales[17] =
7612 {
7613 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7614 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7615 };
7616
7617 973 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7618 973 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7619 973 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7620 973 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7621 973 int32_t sc = 6;
7622
7623 973 bool done=false, redraw=true;
7624
7625 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7626
7627
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7628 {
7629 enter_sys_pal();
7630 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7631 exit_sys_pal();
7632 return;
7633 }
7634
7635 973 clear_to_color(mappic, WHITE);
7636
7637 973 auto prev_viewport = viewport;
7638 973 viewport.x = 0;
7639 973 viewport.y = 0;
7640
7641 // draw the map
7642 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7643 973 combotile_add_x = 256;
7644 973 combotile_add_y = 0;
7645
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7646 {
7647
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7648 {
7649
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7650 78864 continue;
7651
7652 45680 int screen = map_scr_xy_to_index(x, y);
7653 45680 auto scrs = loadscr2(screen);
7654 45680 mapscr* scr = &scrs[0];
7655
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7656 continue;
7657
7658 screen_handles_t screen_handles;
7659
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7660
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7661
7662 45680 int xx = 0;
7663 45680 int yy = -playing_field_offset;
7664
7665
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7666 {
7667
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7668
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7669 20 }
7670
7671
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7672 {
7673
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7674
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7675 175 }
7676
7677
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7678
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7679
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7680
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7681
7682
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7683 {
7684
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7685
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7686 45660 }
7687
7688
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7689
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7690 {
7691
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7692
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7693 {
7694
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7695
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7696 1782 }
7697 41678 }
7698
7699
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7700 {
7701
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7702
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7703 45505 }
7704
7705
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7706
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7707
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7708
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7709 {
7710
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7711
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7712 5784 }
7713
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7714
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7715
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7716 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7717
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7718
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7719
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7720
7721
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7722
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7723 7784 }
7724
7725 973 viewport = prev_viewport;
7726 973 combotile_add_x = 0;
7727 973 combotile_add_y = 0;
7728
7729 973 destroy_bitmap(screen_bmp);
7730 973 clear_keybuf();
7731 973 pause_all_sfx();
7732
7733 // view it
7734 973 int32_t delay = 0;
7735
7736 973 do
7737 {
7738
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7739 29891 load_control_state();
7740
7741 208608 int32_t step = int32_t(16.0/scales[sc]);
7742 208608 step = (step>>1) + (step&1);
7743 208608 bool r = cRbtn();
7744
7745
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7746 {
7747 step <<= 2;
7748 delay = 0;
7749 }
7750
7751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7752 {
7753 if(rUp())
7754 {
7755 py+=step;
7756 redraw=true;
7757 }
7758
7759 if(rDown())
7760 {
7761 py-=step;
7762 redraw=true;
7763 }
7764
7765 if(rLeft())
7766 {
7767 px+=step;
7768 redraw=true;
7769 }
7770
7771 if(rRight())
7772 {
7773 px-=step;
7774 redraw=true;
7775 }
7776 }
7777 else
7778 {
7779
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7780 {
7781 14879 py+=step;
7782 14879 redraw=true;
7783 14879 }
7784
7785
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7786 {
7787 15034 py-=step;
7788 15034 redraw=true;
7789 15034 }
7790
7791
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7792 {
7793 26449 px+=step;
7794 26449 redraw=true;
7795 26449 }
7796
7797
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7798 {
7799 25834 px-=step;
7800 25834 redraw=true;
7801 25834 }
7802 }
7803
7804
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7805 21164 --delay;
7806 else
7807 {
7808 187444 bool a = cAbtn();
7809 187444 bool b = cBbtn();
7810
7811
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7812 {
7813
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7814 1721 delay=8;
7815 1721 redraw=true;
7816 1721 }
7817
7818
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7819 {
7820
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7821 927 delay=8;
7822 927 redraw=true;
7823 927 }
7824 }
7825
7826
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7827 11 --view_map_show_mode;
7828
7829 208608 px = vbound(px,-4096,4096);
7830 208608 py = vbound(py,-1408,1408);
7831
7832 208608 double scale = scales[sc];
7833
7834
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7835 {
7836 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7837 135770 }
7838 else
7839 {
7840 72838 clear_to_color(framebuf,BLACK);
7841 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7842 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7843 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7844
7845 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7846 72838 redraw=false;
7847 }
7848
7849 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7850 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7851
7852
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7853 {
7854 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7855 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7856 201142 }
7857
7858
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7859 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7860
7861
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7862 {
7863 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7864 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7865 }
7866
7867 208608 advanceframe(false, false);
7868
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7869 178717 load_control_state();
7870
7871
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if(getInput(btnS, true, false, true)) //rSbtn
7872 972 done = true;
7873
7874
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 207635 times.
417216 }
7875
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7876
7877 973 ViewingMap = false;
7878 973 destroy_bitmap(mappic);
7879 973 resume_all_sfx();
7880 973 }
7881
7882 1075 int32_t onViewMap()
7883 {
7884
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7885 {
7886 973 clear_to_color(framebuf,BLACK);
7887 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7888 973 advanceframe(true);
7889 973 ViewMap();
7890 973 }
7891
7892 1075 return D_O_K;
7893 }
7894
7895 35695413 bool isGrassType(int32_t type)
7896 {
7897
2/2
✓ Branch 0 taken 35019001 times.
✓ Branch 1 taken 676412 times.
35695413 switch(type)
7898 {
7899 case cTALLGRASS:
7900 case cTALLGRASSNEXT:
7901 case cTALLGRASSTOUCHY:
7902 676412 return true;
7903 }
7904
7905 35019001 return false;
7906 35695413 }
7907
7908 20914 bool isFlowersType(int32_t type)
7909 {
7910
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7911 {
7912 case cFLOWERS:
7913 case cFLOWERSTOUCHY:
7914 4340 return true;
7915 }
7916
7917 16574 return false;
7918 20914 }
7919
7920 bool isGenericType(int32_t type)
7921 {
7922 switch(type)
7923 {
7924 case cTRIGGERGENERIC:
7925 return true;
7926 }
7927
7928 return false;
7929 }
7930
7931 26056 bool isBushType(int32_t type)
7932 {
7933
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7934 {
7935 case cBUSH:
7936 case cBUSHNEXT:
7937 case cBUSHTOUCHY:
7938 case cBUSHNEXTTOUCHY:
7939
7940 5142 return true;
7941 }
7942
7943 20914 return false;
7944 26056 }
7945
7946 bool isSlashType(int32_t type)
7947 {
7948 switch(type)
7949 {
7950 case cSLASH:
7951 case cSLASHITEM:
7952 case cSLASHTOUCHY:
7953 case cSLASHITEMTOUCHY:
7954 case cSLASHNEXT:
7955 case cSLASHNEXTITEM:
7956 case cSLASHNEXTTOUCHY:
7957 case cSLASHNEXTITEMTOUCHY:
7958 return true;
7959 }
7960
7961 return false;
7962 }
7963
7964 15695 bool isCuttableNextType(int32_t type)
7965 {
7966
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
7967 {
7968 case cSLASHNEXT:
7969 case cSLASHNEXTITEM:
7970 case cTALLGRASSNEXT:
7971 case cBUSHNEXT:
7972 case cSLASHNEXTTOUCHY:
7973 case cSLASHNEXTITEMTOUCHY:
7974 case cBUSHNEXTTOUCHY:
7975 5907 return true;
7976 }
7977
7978 9788 return false;
7979 15695 }
7980
7981 17546 bool isTouchyType(int32_t type)
7982 {
7983
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
7984 {
7985 case cSLASHTOUCHY:
7986 case cSLASHITEMTOUCHY:
7987 case cBUSHTOUCHY:
7988 case cFLOWERSTOUCHY:
7989 case cTALLGRASSTOUCHY:
7990 case cSLASHNEXTTOUCHY:
7991 case cSLASHNEXTITEMTOUCHY:
7992 case cBUSHNEXTTOUCHY:
7993 11496 return true;
7994 }
7995
7996 6050 return false;
7997 17546 }
7998
7999 29325925 bool isCuttableType(int32_t type)
8000 {
8001
2/2
✓ Branch 0 taken 28876660 times.
✓ Branch 1 taken 449265 times.
29325925 switch(type)
8002 {
8003 case cSLASH:
8004 case cSLASHITEM:
8005 case cBUSH:
8006 case cFLOWERS:
8007 case cTALLGRASS:
8008 case cTALLGRASSNEXT:
8009 case cSLASHNEXT:
8010 case cSLASHNEXTITEM:
8011 case cBUSHNEXT:
8012
8013 case cSLASHTOUCHY:
8014 case cSLASHITEMTOUCHY:
8015 case cBUSHTOUCHY:
8016 case cFLOWERSTOUCHY:
8017 case cTALLGRASSTOUCHY:
8018 case cSLASHNEXTTOUCHY:
8019 case cSLASHNEXTITEMTOUCHY:
8020 case cBUSHNEXTTOUCHY:
8021 449265 return true;
8022 }
8023
8024 28876660 return false;
8025 29325925 }
8026
8027 17322 bool isCuttableItemType(int32_t type)
8028 {
8029
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8030 {
8031 case cSLASHITEM:
8032 case cBUSH:
8033 case cFLOWERS:
8034 case cTALLGRASS:
8035 case cTALLGRASSNEXT:
8036 case cSLASHNEXTITEM:
8037 case cBUSHNEXT:
8038
8039 case cSLASHITEMTOUCHY:
8040 case cBUSHTOUCHY:
8041 case cFLOWERSTOUCHY:
8042 case cTALLGRASSTOUCHY:
8043 case cSLASHNEXTITEMTOUCHY:
8044 case cBUSHNEXTTOUCHY:
8045 16898 return true;
8046 }
8047
8048 424 return false;
8049 17322 }
8050
8051 66 bool is_push(mapscr* m, int32_t pos)
8052 {
8053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8054 return true;
8055 66 newcombo const& cmb = combobuf[m->data[pos]];
8056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8057 return true;
8058
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8059 14 return true;
8060
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8061 return true; //Counts as 'pushblock' flag
8062 52 return false;
8063 66 }
8064
8065 404 static std::map<int, screen_state_t> screen_states;
8066
8067 35830 std::map<int, screen_state_t>& get_screen_states()
8068 {
8069 35830 return screen_states;
8070 }
8071
8072 44147606 screen_state_t& get_screen_state(int screen)
8073 {
8074 44147606 return screen_states[screen];
8075 }
8076
8077 568 void clear_screen_states()
8078 {
8079 568 screen_states.clear();
8080 568 }
8081
8082 1438 void screen_item_set_state(int screen, ScreenItemState state)
8083 {
8084 1438 get_screen_state(screen).item_state = state;
8085 1438 }
8086
8087 36982 void mark_visited(int screen)
8088 {
8089
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36507 times.
36982 if (screen < 0x80)
8090 {
8091
2/2
✓ Branch 0 taken 24597 times.
✓ Branch 1 taken 11910 times.
36507 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8092 11910 game->maps[mapind(cur_map, screen)] |= mVISITED;
8093
8094 36507 markBmap(-1, screen);
8095 36507 }
8096 36982 }
8097